Multiple insert into DB is this possible?

Hello

Having created an insert into my DB for my feed I now need to be able to update it if a record exists. I have got this far with it but cannot get the update to work.


$xml= 'test-feed.xml'; // URL for feed.

try{
  $feed = new SimpleXMLElement($xml, null, true);
}catch(Exception $e){
  echo $e->getMessage();
  exit;
}

foreach($feed->property as $property)
{


      $id = mysql_real_escape_string($property->id);

      $query = "SELECT prop_id FROM images WHERE prop_id = '$id'";

      $result = mysql_query($query);

      $rows = mysql_num_rows($result);

 }

      if($rows > 1)

      {
      
$sqlxml = "";
$arr = array();

foreach($feed->property as $property) {

 $propertyid = (string)$property->id;
 
 foreach($property->images->image as $image) {
  $i = 0;
  $url = (string)$image->url;
  $arr[] = "UPDATE images SET `url` = '$url' WHERE `prop_id` =  '$propertyid' , ";
 $i++; 
  
 }

}

foreach($arr as $result) $sql .= $result;

$sql = rtrim($sql, ",");

echo $sql;

}

else

{

echo "    NO DATA SO INSERT";

}

if(!mysql_query($sql)){
  echo '<h1 style="color: red;">Error</h1><p>', mysql_error(), '</p>';
}
else
{

  echo '<h1 style="color: red;">Property data successfully added to database!</h1>';
}

The query structure echos as:


UPDATE images SET url = 'ImageId=X1000245' WHERE prop_id = 'A1234', 
UPDATE images SET url = 'ImageId=X1000296' WHERE prop_id = 'A1234', 
UPDATE images SET url = 'ImageId=X1000237' WHERE prop_id = 'ABC1234'

You have an error in your SQL syntax; check the manual that corresponds 
to your MySQL server version for the right syntax to use near ' UPDATE 
images SET `url` = '

Am I on the right track here? Can I update multiples using different WHERE clauses in the same query. I have been slugging away at this for a couple of days trying to figure it out for myself but once again I have to ask of you guys once more.

Thanks in advance
Colin

No you can’t do that.

If however, prop_id is unique, you can create an INSERT statement in a similar fashion and simply instruct the database to UPDATE ON DUPLICATE KEY. :slight_smile:

Hi Anthony

Blast where do I go from here. Prop_id is not unique only the URL which I am trying to update. I used UPDATE ON DUPLICATE KEY on another table and it works a charm.

– Table structure for table images

CREATE TABLE IF NOT EXISTS images (
id int(20) NOT NULL AUTO_INCREMENT,
prop_id varchar(20) CHARACTER SET utf8 NOT NULL,
url varchar(300) CHARACTER SET utf8 NOT NULL,
primary enum(‘1’,‘0’) CHARACTER SET utf8 NOT NULL DEFAULT ‘0’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2227 ;

I am at a total loss as to how to progress with this. I need to parse the feed, check if prop_id exists, if it does update it else insert new row(s)

HELP!!!

Colin

you cannot concatenate SQL statements with commas, you have to use semicolons


UPDATE images SET url = 'ImageId=X1000245' WHERE prop_id = 'A1234'[COLOR="Red"];[/COLOR] 
UPDATE images SET url = 'ImageId=X1000296' WHERE prop_id = 'A1234'[COLOR="red"];[/COLOR]  
UPDATE images SET url = 'ImageId=X1000237' WHERE prop_id = 'ABC1234'[COLOR="red"];[/COLOR] 

Thanks for the reply I will take another look at my code.

Colin

Ok I have modified my code to use semicolons:

UPDATE images SET url = 'ImageId=X1000245' WHERE prop_id = 'A1234'; 
UPDATE images SET url = 'ImageId=X1000296' WHERE prop_id = 'A1234'; 
UPDATE images SET url = 'ImageId=X1000237' WHERE prop_id = 'ABC1234';

You have an error in your SQL syntax; check the manual that corresponds 
to your MySQL server version for the right syntax to use near 'UPDATE images SET `url`=

Without success.

Colin

I dont think the mysql extension will run a batch of SQL statements in one go.

MySQLi extension will using PHP: mysqli::multi_query - Manual

Can anyone else confirm this?

Colin

The manual confirms this. :stuck_out_tongue:

You’ll have to move your other functions over to the mysqli alternative though.

You say prop_id isn’t unique, yet use it as a key when updating the table; which implies it is unique.

Maybe this needs addressing.

Anthony.

!! CAUTION !!
Setting the interface up to allow multiple queries per statement makes the system more vulnerable to SQL injection attack. It’s ok to proceed with this approach, but keep that vulnerability in mind while doing so.

Thanks Anthony for the confirmation. I have no experience off MySQLi at all so another chance to learn something new. (Just what I need at the moment :)) Maybe I need to restructure my DB but not sure how I could make what I have any better, although I feel sure somebody would disagree with that statement.

prop_id is unique to the property but is inserted into the db multiple times, once for each image. prop_id ABC123 can have for example 10 image urls attached to it so the prop_id field will contain 10 ABC123 entries.

I did consider creating any extra field, strip the url down to say the last 5 digits of the url and insert that as a unique ID then use UPDATE ON DUPLICATE KEY. Workable solution perhaps?

Thanks Michael for your warning I will keep that in mind.

Colin

Still having difficulty with this. I have changed to mysqli and have the following which almost works:


// Connect to database
         $db=new mysqli('localhost',' ',' ');

         if (mysqli_connect_errno()) {
              die( 'Connect failed: ' . mysqli_connect_error() );
         }

         $db->select_db('feed')
         or die( 'select_db failed: '.$db->error );

 // URL for feed.
$xml= 'test-feed.xml';

try{
  $feed = new SimpleXMLElement($xml, null, true);
}catch(Exception $e){
  echo $e->getMessage();
  exit;
}



$sqlxml = "";
$arr = array();

foreach($feed->property as $property) {

 $propertyid = (string)$property->id;
 
 foreach($property->images->image as $image) {
  $i = 0;
  $url = (string)$image->url;
  $arr[] = "UPDATE images SET `url` = '$url' WHERE `prop_id` =  '$propertyid'; ";
 $i++; 
  
 }

}

foreach($arr as $result) $sql .= $result;

$sql = rtrim($sql, "; ");



$sqlResult = $db->multi_query($sql);

echo $sql;


   if($sqlResult == true) 
   
   {
       echo " Successfully Inserted Records";
   } 

else 

{
       echo " An Error Occured While Inserting Records";
   }

The query structure echos the following:

UPDATE images SET `url` = 'http://ImageId=X123' WHERE `prop_id` = 'A1234';
UPDATE images SET `url` = 'http://ImageId=X1044296' WHERE `prop_id` = 'A1234'; 
UPDATE images SET `url` = 'http://ImageId=X1000237' WHERE `prop_id` = 'A1234'; 
UPDATE images SET `url` = 'http://ImageId=X1000231' WHERE `prop_id` = 'ABC1234'; 
UPDATE images SET `url` = 'http://ImageId=X1000232' WHERE `prop_id` = 'ABC1234' 
Successfully Inserted Records   

The problem seems to be with the loop, all the url entries for each prop_id have the last value in the loop added to the db and not as echoed.


id        prop_id                    url

4587     A1234         http://ImageId=X10001235
4588     A1234         http://ImageId=X10001235
4589     A1234         http://ImageId=X10001235
4590     A1234         http://ImageId=X10001235
4591     A1234         http://ImageId=X10001235
4592     A1234         http://ImageId=X10001235

Thanks in advance

Colin

Try something along these lines Colin. :slight_smile:


<?php
error_reporting(-1);
ini_set('display_errors', true);

$queries = array();

foreach($feed->property as $property){
  
  $id = $property->id;
  
  foreach($property->images->image as $image){
    
    $query = sprintf(
      "UPDATE images SET `url` = '%s' WHERE `prop_id` = '%s';",
      $db->real_escape_string((string)$image->url),
      $db->real_escape_string((string)$id)
    );
    
    array_push($queries, $query);
    
  }
  
}

if($db->multi_query(implode(null, $queries))){
  /*
   see http://www.php.net/manual/en/mysqli.multi-query.php#102837
  */
  while($db->more_results() && $db->->next_result()){
    
  }
}

Hi Anthony

Thanks for the reply. In my frustration I decided to go in a different direction with this and put a unique field into the db. I am generating this by creating an extra field named pid. Then I am adding the image_id to the prop_id, which always creates a unique, insert this as the pid then I use ON DUPLICATE UPDATE.

Well it works!!

I did look at the PHP manual for multi queries with mysqli but to be honest I couldnt get my head around it :frowning:

So I have ended up with the code below which may need a few tweaks to make it safe.

$xml = 'test-feed.xml'; // URL for feed.



try{
  $feed = new SimpleXMLElement($xml, null, true);
}catch(Exception $e){
  echo $e->getMessage();
  exit;
}

$sql = 'INSERT INTO images (`prop_id`, `url`, `pid`) VALUES ';

$sqlxmlarr = array();

foreach($feed->property as $property) {

 $propertyid = (string)$property->id;
 
 
  
  $i = 0;
foreach ($property->images->image as $image) {
  
   $url = (string)$image->url;
   $imageid = (int)$image['id'];
   $pid = "$propertyid-$imageid";
   $sqlxmlarr[] = "('".$propertyid." ', '".$url."', '".$pid."'),";
   $i++;
  
  }
  
 

}

foreach($sqlxmlarr as $sqlchk) $sql .= $sqlchk;
 

$sql = rtrim($sql, ',') .  ' ON DUPLICATE KEY UPDATE url = VALUES (url)';
 

echo $sql;


if(!mysql_query($sql)){
  echo '<h1 style="color: red;">Error</h1><p>', mysql_error(), '</p>';
}
else
{

  echo '<h1 style="color: red;">Property image records have been added to the database</h1>';
}

I now have this:


id        prop_id                    url                  pid

4587     A1234         http://ImageId=X10001235         A1234-1
4588     A1234         http://ImageId=X10001235         A1234-2
4589     A1234         http://ImageId=X10001235         A1234-3
4590     A1234         http://ImageId=X10001235         A1234-4
4591     A1234         http://ImageId=X10001235         A1234-5
4592     A1234         http://ImageId=X10001235         A1234-6