0

I have an array stored in a variable $contactid. I need to run this query to insert a row for each contact_id in the array. What is the best way to do this? Here is the query I need to run...

$contactid=$_POST['contact_id'];
$eventid=$_POST['event_id'];
$groupid=$_POST['group_id'];

mysql_query($query);
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid','$groupid')";
Budove
  • 403
  • 2
  • 8
  • 19
  • 1
    The best way would involve switching to PDO / mysqli and prepared statements to get rid of the sql injection problem that you have. Apart from that, what contact ID do you mean to use, the posted one or the one from the array? – jeroen Nov 28 '12 at 20:55
  • will the event id and group id be same for all contacts in the array? – soft genic Nov 28 '12 at 20:55
  • yes the event id and group id will be the same for all contacts – Budove Nov 28 '12 at 20:56
  • As suggested, use PDO instead of mysql_ functions. Also, don't define $query below the request to execute the query. Obviously that won't work. TO answer your question though - look into a foreach loop. It's basic php. – Kai Qing Nov 28 '12 at 20:56
  • well you can use for each for that... easy way and a good way – soft genic Nov 28 '12 at 20:57
  • [**Please, don't use `mysql_*` functions in new code**](http://bit.ly/phpmsql). They are no longer maintained and the [deprecation process](http://j.mp/Rj2iVR) has begun on it. See the [**red box**](http://j.mp/Te9zIL)? Learn about [*prepared statements*](http://j.mp/T9hLWi) instead, and use [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli) - [this article](http://j.mp/QEx8IB) will help you decide which. If you choose PDO, [here is a good tutorial](http://j.mp/PoWehJ). – Madara's Ghost Nov 28 '12 at 20:58

5 Answers5

3

Use a foreach loop.

$query = "INSERT INTO attendance (event_id,contact_id,group_id) VALUES ";

foreach($contactid as $value)
{
    $query .= "('{$eventid}','{$value}','{$groupid}'),";
}

mysql_query(substr($query, 0, -1));

The idea here is to concatenate your query string and only make 1 query to the database, each value-set is separated by a comma

phpisuber01
  • 7,585
  • 3
  • 22
  • 26
  • 1
    umm... you tried this? mysql_query was patched like years and years ago so anyone wouldn't be able to do this. – eis Nov 28 '12 at 20:59
  • @softgenic hehe, its always a race for these quick ones – phpisuber01 Nov 28 '12 at 20:59
  • @eis Oh really? Good to know we can all learn something here :-) – phpisuber01 Nov 28 '12 at 21:00
  • @eis hmmm well is there anyother way to run query cause i never tried those.. I always used/use mysql_query – soft genic Nov 28 '12 at 21:04
  • If you just concatenate the values (separated by a comma) instead and put `INSERT INTO attendance (event_id,contact_id,group_id) VALUES` before the loop, it would actually work :-) – jeroen Nov 28 '12 at 21:04
  • @jeron, Yup! Just editted my answer for that same idea. Thanks all, good to know for when I `NEVER` user mysql* in the future.. :-) – phpisuber01 Nov 28 '12 at 21:06
  • Well, with a bit of creativity and without the last line, this could easily be converted to a prepared statement to be used with for example PDO. – jeroen Nov 28 '12 at 21:08
  • This actually works, but I'm getting an error 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 '' at line 1. – Budove Nov 28 '12 at 21:20
  • @Budove can you `echo $query;` and comment out the mysql_query and paste your SQL query. Might help debug it. – phpisuber01 Nov 28 '12 at 21:27
  • Yeah, just tested this code on my local and it works perfectly.. Thinking you might have some unescaped characters in there... – phpisuber01 Nov 28 '12 at 21:29
  • Ok. There's a final comma at the end of the last group of values. Could that be the issue? – Budove Nov 28 '12 at 21:31
  • @Budove Nope, the `mysql_query` has a `substr($query, 0, -1)` which takes that away. – phpisuber01 Nov 28 '12 at 21:31
  • INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('1014','1308','6'),('1014','1220','6'),('1014','1346','6'),('1014','1237','6'),('1014','1091','6'),('1014','1086','6'),('1014','1070','6'),('1014','1347','6'),('1014','1206','6'),('1014','1089','6'),('1014','1088','6'),('1014','1214','6'),('1014','1300','6'),('1014','1049','6'), – Budove Nov 28 '12 at 21:32
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20272/discussion-between-phpisuber01-and-budove) – phpisuber01 Nov 28 '12 at 21:39
  • Replace the following line, you have some ODD characters being put in there.. `$query .= "('" . trim($eventid) . "','" . trim($value) . "','" . trim($groupid) . "'),";` – phpisuber01 Nov 28 '12 at 21:40
  • This is in your query: `‌​1014,1206,6` – phpisuber01 Nov 28 '12 at 21:42
  • I went to chat but you're not there. Those characters would be an extra quotation mark would it not? – Budove Nov 28 '12 at 22:15
  • Add escaping. If you're actually going to use mysql_query, you might as well add mysql_real_escape_string, too. – eis Nov 29 '12 at 06:58
2

Since no one hasn't stated that yet, you actually cannot do this:

$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1]);
INSERT INTO [Table] ([Column List])
VALUES ([Value List 2]);
';
mysql_query($query);

as this has been prevented to prevent sql injections in the mysql_query code. You cannot have semicolon within the given query param with mysql_query. With the following exception, taken from the manual comments:

The documentation claims that "multiple queries are not supported".

However, multiple queries seem to be supported. You just have to pass flag 65536 as mysql_connect's 5 parameter (client_flags). This value is defined in /usr/include/mysql/mysql_com.h:

#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */

Executed with multiple queries at once, the mysql_query function will return a result only for the first query. The other queries will be executed as well, but you won't have a result for them.

That is undocumented and unsupported behaviour, however, and easily opens your code to SQL injections. What you can do with mysql_query, instead, is

$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1])
     , ([Value List 2])
       [...]
     , ([Value List N])
';
mysql_query($query);

so you can actually insert multiple rows with a one query, and with one insert statement. In this answer there's a code example for it which doesn't concatenate to a string in a loop, which is better than what's suggested in this thread.


However, disregarding all the above, you're probably better of still to use a prepared statement, like

$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
    $stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
    $stmt->execute();
}
$stmt->close();
Community
  • 1
  • 1
eis
  • 51,991
  • 13
  • 150
  • 199
1

Use something like the following. Please note that you shouldn't be using mysql_* functions anymore, and that your code is suseptible to injection.

for ($i = 0; $i < count($contactid); $i++) {
    $query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid[$i]','$groupid')";
    mysql_query($query);
}
WhoaItsAFactorial
  • 3,538
  • 4
  • 28
  • 45
  • that's great, but only if the array is small. If you try to execute this loop for 100 elements for an instance I think it'd take a while.. – vlex Nov 28 '12 at 20:59
  • 1
    @vlex That is very true, unfortunately, you can't add multiple rows in the same query though. – WhoaItsAFactorial Nov 28 '12 at 21:02
  • @softgenic Why foreach over a standard for loop? (Honestly looking for your reasoning as I don't see an advantage to one over the other.) – WhoaItsAFactorial Nov 28 '12 at 21:05
  • Actually you can - you just need to use a couple of additional variables and parse the elements in strings. Once done so, you can concatenate them all into one big string and use it as a query, which would be the quickest to execute. I was going to propose that in my suggestion beneath, but never got example source to start with :) edit: actually truth to be told it depends on how the DB is built. You're right though. – vlex Nov 28 '12 at 21:05
  • Where is $connectionString coming from? – Budove Nov 28 '12 at 21:08
  • `foreach` would be better in case the keys are non-numerical / don't start at 0 / have missing values in between, etc. – jeroen Nov 28 '12 at 21:11
  • @Budove Sorry about that, I've been using odbc_exec so much that I got its syntax mixed with mysql_query. Edit has been made removing the $connectionString reference. – WhoaItsAFactorial Nov 29 '12 at 12:39
  • Thank you Jeremy1026. This is writing the correct values to the database but it seems as if the last row written is trying to duplicate. "Error Reported Duplicate entry '1016-1242-6' for key 1 " 1016-1242-6 is the last row written to the database. – Budove Nov 29 '12 at 20:35
0

I'm not sure running multiple queries is the best thing to do, so won't recommend making a for loop for example, that runs for each element of the array. I would rather say, make a recursive loop, that adds the new elements to a string, that then gets passed to the query. In case you can give us a short example of your DB structure and how you'd like it to look like (i.e. how the array should go into the table), I could give you an example loop syntax.

Cheers!

vlex
  • 128
  • 6
0

What about:

$contactIds = $_POST['contact_id'];
$eventIds = $_POST['event_id'];
$groupIds = $_POST['group_id'];

foreach($contactIds as $key => $value)
{
    $currentContactId = $value;
    $currentEventId = $eventIds[$key];
    $currentGroupId = $groupIds[$key];

    $query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$currentEventId','$currentContactId','$currentGroupId')";

    mysql_query($query);
}

Well, you could refactor that to insert everything in a single query, but you got the idea.

rafaame
  • 822
  • 2
  • 12
  • 22