PHP MySQLi insert ids from multi_query() - php

Is there a way to get the last generated auto_increment IDs after inserting several rows with mysqli multi_query function?
EDIT:
I managed to get it work by adding SELECT LAST_INSERT_ID(); after each INSERT query in the multi query and then use the mysqli_use_result to get all ids, and I think this is the best way.

You can fetch the different insert ids by calling MySQLi's next_result() for each consecutive insert statement. As far as I know, you don't have to store any results as long as the queries are insert statements or something else that doesn't return a result set.
$sql = new MySQLi("...");
$query = "INSERT STATEMENT NUMBER ONE;";
$query .= "INSERT STATEMENT NUMBER TWO;";
$query .= "INSERT STATEMENT NUMBER THREE";
$sql->multi_query($query);
// The first insert id will be available at once
$id1 = $sql->insert_id;
// The second needs to be handeled a little differently
$sql->next_result();
$id2 = $sql->insert_id;
// And lastly the third one
$sql->next_result();
$id3 = $sql->insert_id;
You can also put this in a loop if you are unsure of how many insert statements there are:
$ids = array();
do
{
$ids[] = $sql->insert_id;
$sql->next_result();
} while($sql->more_results());
This is untested pseudo code (as you might have figured), but it should work.

Related

Merge multiple foreach MySQL insert statements into one with PHP array data

I have a PHP array with different items and their respective values, and would need to update each row for each item in a database. Is there a way to only have one query to execute, instead of multiple foreach queries?
foreach($array as $key=>$item){
$image_id = $item['id'];
$order_id = $item['order_id'];
$sql = "UPDATE images SET order_id='$order_id' WHERE id='$image_id'";
$query = mysqli_query($connection, $sql);
} // end for each
You can't really combine it into one query using UPDATE, as the value and condition come in pairs (the value and condition is different for each row you are updating).
There is a hacky fix with INSERT INTO..ON DUPLICATE KEY UPDATE, but I would refrain from using that - see the question linked by RiggsFolly in the comments.
When using a prepared statement, you can execute the same query multiple times (you would have to query it multiple times anyways, even with mysqli_query(), but this is optimized and more secure when using a prepared statement).
$sql = "UPDATE images SET order_id=? WHERE id=?";
$stmt = $connection->prepare($sql);
foreach($array as $key=>$item){
$stmt->bind_param("ss", $item['order_id'], $item['id']);
$stmt->execute();
}
$stmt->close();
If your IDs are integers instead of strings, replace the respective s with an i.
PHP.net on mysqli::prepare()
PHP.net on mysqli-stmt::bind_param()
PHP.net on mysqli-stmt::execute()

PHP/MYSQL:Carry out UPDATE within SELECT query

There are many questions on SO about this but I cannot find one that quite meets my situation.
I want to use the values in some fields/columns of a table to set the value of a third field/column
In other words something like:
table races
athleteid|difficulty|score|adjustedscore
$sqlSelect = "SELECT athleteid,difficulty,score FROM races";
$res = mysql_query($sqlSelect) or die(mysql_error());
while ($row = mysql_fetch_array($res)){
$adjustedscore=difficulty*score;
$sqlupdate = "UPDATE race, set adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
$resupdate = mysql_query($sqlupdate);
}
My understanding, however, is that MYSQL does not support update queries nested in select ones.
Note, I have simplified this slightly. I am actually calculating the score based on a lot of other variables as well--and may join some tables to get other inputs--but this is the basic principal.
Thanks for any suggestions
You can run:
UPDATE `races`
SET `adjustedscore` = `difficulty` * `score`
WHERE `athleteid` IN (1, 2, 3, ...)
First of all, as previous commentators said, you should use PDO instead of mysql_* queries.
Read about PDO here.
When you'll get data from DB with your SELECT query, you'll get array. I recommend you to use fetchAll() from PDO documentation.
So, your goal is to save this data in some variable. Like you did with $row.
After that you'll need to loop over each array and get your data:
foreach($row as $r) {
//We do this to access each of ours athlete data
$adjustedscore= $row[$r]["difficulty"]* $row[$r]["score"];
//Next row is not clear for me...
$query = "UPDATE race SET adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
And to update we use PDO update prepared statement
$stmt = $dbh->prepare($query);
$stmt->execute();
}

how to get mysql id of number of effect row

I perform the mysql query to check if any number of row effected on the user input data with the help of mysql_num_rows($query). Only one row will effect always as I made some rows are unique. If one row effect, I want to get the ID of that Row. I means the auto increment ID of the same row.
The same row contains many fields, its better if I come to know how to get the entry of other fields.
Thanks stack for your solutions.
Have you tried SELECT id FROM table WHERE value=condition? If you query that you will get the id of the row that matches your condition. Replace id with the identifactor row, table with your table name, value and condition with your conditions.
$query = "SELECT id FROM table WHERE value=condition";
$result = mysql_query($query);
if ($row = mysql_fetch_row($result)) {
//$row contains valid information.
}
Btw: don´t use mysql_* anymore, its deprecated, look at PDO or mysqli_*
$query = "SELECT mysql_id
FROM table";
$stmt = $db->prepare($query);
$stmt->execute();
$id = $stmt->fetchColumn();
You'll probably have to add a "WHERE" clause to your query statement and then pass the values into in array using a prepared statement.
just use mysql_insert_id();
this function after executing the insert query.
$query = "INSERT INTO test (value) VALUES ('test')";
mysql_query( $query );
$lastInsertId=mysql_insert_id();
echo $lastInsertId;

What Does mysqli_store_result() Actually Do?

I want to understand that What mysqli_store_result Actually does? When I visited the PHP Manual of mysqli_store_result, I found the definiton
mysqli_store_result — Transfers a result set from the last query
The Question is Where it transfers the result set?
Actually I was getting the error "Commands out of sync; you can't run this command now" after executing mysqli_multi_query But When I used the following method, the Error gone.
mysqli_multi_query($connection,$query);
do
{
mysqli_store_result($connection);
}
while(mysqli_next_result($connection));
Now, Should I use this mysqli_store_result($connection) and mysqli_next_result($connection) after each mysqli_query or just after mysqli_multi_query Because I have read in PHP Manaul that
"Although it is always good practice to free the memory used by the
result of a query using the mysqli_free_result() function, when
transferring large result sets using the mysqli_store_result() this
becomes particularly important."
Source: PHP: mysqli_store_result
One More Question Arises When I executed the above mentioned mysqli_multi_query($connection,$query); I put a statement echo 'storing result <br />' like below
do
{
echo 'storing result <br />
mysqli_store_result($connection);
}
while(mysqli_next_result($connection));
Although There were only Two INSERT queries in the $query but It gave the following output
storing result
storing result
storing result
storing result
It means there were four result sets that were transferred. I can't understand this situation.
One Last Question. Does the above mentioned do while process will effect the performance?
Previous comments have stated that mysqli_store_result() is not to be used with INSERT statements, but no one has mentioned the actual appropriate function: mysqli_affected_rows().
If your statement returns a record set and you want to check it numerically, then use mysqli_num_rows().
If dealing with a mixture, this might get you started:
$queries[] = "INSERT INTO TestTable (Column1) VALUES ('TEST1')";
$queries[] = "SELECT * FROM TestTable WHERE Column1 LIKE 'TEST%'";
$queries[] = "INSERT INTO TestTable (Column1) VALUES ('TEST2')";
$queries[] = "SELECT * FROM TestTable WHERE Column1 LIKE 'TEST%'";
$queries[] = "DELETE FROM TestTable WHERE Column1 LIKE 'TEST%'";
if(mysqli_multi_query($con, implode(';', $queries))){
do{
if($result = mysqli_store_result($con)){
echo "Selected rows = " . mysqli_num_rows($result) . "<br><br>";
mysqli_free_result($result);
}else{
$cumulative_rows += $aff_rows = mysqli_affected_rows($con);
echo "Current Query's Affected Rows = $aff_rows, Cumulative Rows = $cumulative_rows<br><br>";
}
} while(mysqli_more_results($con) && mysqli_next_result($con));
}
Outputs:
Current Query's Affected Rows = 1, Cumulative Affected Rows = 1
Selected rows = 1
Current Query's Affected Rows = 1, Cumulative Affected Rows = 2
Selected rows = 2
Current Query's Affected Rows = 2, Cumulative Affected Rows = 4
An important note to anyone new to the topic of database querying: If you are using user-supplied / externally-sourced / untrustworthy data, then you should be using prepared statements with placeholders for security/stability (mysqli_multi_query() DOES NOT AFFORD THIS). Using mysqli_multi_query() seems like a cool, concise way to send a batch of queries, but there are not many compelling reasons/scenarios to use this function over sending queries one-at-a-time in a secure manner.
It actually will fetch the whole resultset from the MySQL. You can then mysqli_data_seek() to move to a particular row within the set. So that means all of the results will be stored on the php-side after the first call, and subsequent calls will just request the results from php

Updating multiple rows in MySQL

I'm trying to update multiple rows in one table in MySQL database by doing this. And its not working.
$query = "UPDATE cart SET cart_qty='300' WHERE cart_id = '21';
UPDATE cart SET cart_qty='200' WHERE cart_id = '23';
UPDATE cart SET cart_qty='100' WHERE cart_id = '24';";
mysql_query($query,$link);// $link is specified above
Anyone know what is wrong with this.
From the PHP documentation:
mysql_query() sends a unique query (multiple queries are not supported)
The ; separates SQL statements, so you need to separate the queries if you want to continue using the mysql_query function...
mysql_query can't use multiple queries.
The easiest thing is to just run them separately. I believe you can do multi query but I haven't tried it.
$updateArray = array(21=>300,23=>200,24=>100);
foreach($updateArray as $id=>$value)
{
$query = "UPDATE cart SET cart_qty='$value' WHERE cart_id = '$id'";
mysql_query($query,$link);// $link is specified above
}
This will accept a combination of IDs and their corresponding cart value. Looping though, it builds the query and executes it. The array can then come from a variety of sources (results from another query, form inputs or, as in this case, hard-coded values)
Update:
If you really need to execute all in one, heres the PHP info on multi query:
mysqli::multi_query
You can do it this way:
UPDATE table
SET col1 = CASE id
WHEN id1 THEN id1_v1,
WHEN id2 THEN id2_v1
END
col2 = CASE id
WHEN id1 THEN id1_v2,
WHEN id2 THEN id2_v2
END
WHERE id IN (id1, id2)
This example shows updating two different columns in two different rows so you can expand this to more rows and columns by cludging together a query like this. There might be some scaling issues that makes the case statement unsuitable for a very large number of rows.
You'll need to send them as separate queries. Why not add the queries as strings to an array, then iterate through that array sending each query separtely?
Also check this thread for another idea
This isn't the best method.. But if you need to do multiple queries you could use something like...
function multiQuery($sql)
{
$query_arr = explode(';', $sql);
foreach ($query_arr as $query)
{
mysql_query($query);
}
}
another example of a helper query
function build_sql_update($table, $data, $where)
{
$sql = '';
foreach($data as $field => $item)
{
$sql .= "`$table`.`$field` = '".mysql_real_escape_string($item)."',";
}
// remove trailing ,
$sql = rtrim($sql, ',');
return 'UPDATE `' . $table .'` SET '.$sql . ' WHERE ' .$where;
}
echo build_sql_update('cart', array('cart_qty' => 1), 'cart_id=21');

Categories