mysql using lastInsertID in the same mysql insert? - php

I am inserting a single row into a table, one of the columns though needs the lastInsertID to append another column. We are building file names off of record IDs. Instead of doing a 2nd update to the newly inserted record, is it possible to get the value of the ID column and append to it in the same mysql insert?
Using PHP, currently I am doing:
$query = "INSERT INTO table (id,idName) values (null,?)" ;
list($lastID,$inError,$inResult) = dbInsert($query,array("")) ;
Then:
$appString = $lastID . "-S1001.pdf" ;
$query = "UPDATE table SET idName=? WHERE id=?" ;
list($upCount,$upError) = dbUpdate($query,array($appString,$lastID)) ;
But is there a way to merge the INSERT and UPDATE into a single statment?
$apString = "-S1001.pdf" ;
$query = "INSERT INTO table (id,idName) values (null,id.$appString)" ;
list($lastID,$inError,$inResult) = dbInsert($query,array()) ;

Why not create a trigger that will do your update whenever you insert a row into the table?
This way, you don't need to manually do the second query. Just the insert.

Related

INSERT MULTIPLE ROWS in Gerund Table using Insert Into Select

I used INSERT INTO SELECT to copy values (multiple rows) from one table to another. Now, my problem is how do I insert rows with its corresponding IDs from different tables (since it's normalized) into a gerund table because it only outputs one row in my gerund table. What should I do to insert multiple rows and their corresponding IDs in the gerund table.
My code for the gerund table goes like this.
$insert = "INSERT INTO table1 SELECT * FROM sourcetable"; // where id1 is pk of table1.
$result =mysqli_query($conn,$insert)
$id1=mysqli_insert_id($conn);
Now table 1 has inserted multiple rows same as the other 2 tables.
Assuming id.. are the foreign keys
INSERT INTO gerundtable (pk, id1,id2,id3) VALUES ($id1,$id2,$id3);
My problem is it doesn't yield multiple rows.
According to MySql documentation:
For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually return the AUTO_INCREMENT key from the first of the inserted rows. This enables multiple-row inserts to be reproduced correctly on other servers in a replication setup.
So, grab the number of records being copied, and the LAST_INSERT_ID() and you should be able to map exact IDs with each copied row.
In the lines of:
$mysqli->query("Insert Into dest_table Select * from source_table");
$n = $mysqli->affected_rows; // number of copied rows
$id1 = $mysqli->insert_id; // new ID of the first copied row
$id2 = $mysqli->insert_id + 1; // new ID of the second copied row
$id3 = $mysqli->insert_id + 2; // new ID of the third copied row
...
$mysqli->query("INSERT INTO gerundtable (pk, id1,id2,id3) VALUES ($id1,$id2,$id3)");
Thank you for trying to understand and also answering my question. I resolved my own code. I used while loop to get the ids of every row and didn't use INSERT INTO SELECT.
Here is the run down. SInce I'm just using my phone bare with my way posting.
$sqlselect = SELECT * FROM table1;
While($row=mysqli_fetch_array(table1){
$insertquery...
$id1=mysqli_insert_id($conn)
$insertgerundtable = INSERT INTO gerundtable VALUES ( $id1, $id2);
}

Last insert id issue--How to fetch it

I'm using $id = mysqli_insert_id($connection); to get the last inserted id, but in case if it updates any record in the table, it returns 0 as last inserted id.
Is there any way to handle this?
I want to get id each time weather it's inserting or updating.
Thanks
Edit
I need this id to be used for inserting data into table2
id from tab1
put data into tab2 where id from tab1 is FK
and most important, I'm not using the update with where clause
Here is my code that I'm using
$val = utf8_encode($val);
mysqli_set_charset($connection, 'utf8');
mysqli_query($connection, "SET NAMES 'utf8'");
mysqli_query($connection, "SET FOREIGN_KEY_CHECKS = 0;");
$sql = "INSERT INTO leaks($insert) VALUES($val)";
$sql .= " ON DUPLICATE KEY UPDATE `url` = '".mysqli_real_escape_string($connection,$data['url'])."';";
mysqli_query($connection, ($sql))or die(mysqli_error($connection)."<br />".print($sql));
$id = mysqli_insert_id($connection);
$proofs['leaks_id'] = $id;
mysqli_query($connection, "SET FOREIGN_KEY_CHECKS = 0;");
print_r($id);
$this->insertProofs($connection, $proofs);
connection::close_connection($connection);
Please note down that $this->insertProofs($connection, $proofs); inserts data to table2 on the base of key passed to it
On INSERT
After executing an INSERT query, using mysqli_insert_id() is absolutely fine.
On UPDATE
Depending on your update, you;
Would know the id's you're updating
Know the criteria to search for the id's from the update.
For example, if your UPDATE was something like;
UPDATE `foo` SET `x`='y' WHERE `a`='b'
You can then run
SELECT `id` FROM `foo` WHERE `a`='b'
to fetch the updated id's.
Edit
I see you're using ON DUPLICATE KEY UPDATE.
You can modify your query to become (assuming id is the primary auto_increment key)
ON DUPLICATE KEY UPDATE
`url` = '".mysqli_real_escape_string($connection,$data['url'])."',
id = LAST_INSERT_ID(id)
Then you can use mysqli_insert_id() regardless of if it was an UPDATE or INSERT
For example, if I run (with a record of id=2 exists; so we'll update);
INSERT INTO foobar (id, foo) VALUES (2, 'bar') ON DUPLICATE KEY UPDATE foo = 'baz', id = LAST_INSERT_ID(id);
SELECT LAST_INSERT_ID();
The output is 2, as that was the last insert id.

PHP check if MYSQL query was an insert or update

I have a simple MYSQL query:
INSERT INTO table (col1,col2) VALUES ('1','2')
ON DUPLICATE KEY UPDATE col1 = '1', col2 = '2'
I use PHP PDO statements to query the database. Is there a way to know if the query executed resulted into a new inserted row or an existing was updated?
One way to do so is to get the number of rows before executing the query, then get the number of rows after executing the query, if they're not equal, it means a new row was inserted and if they are equal, it means a row was updated.
$sql = "SHOW TABLE STATUS LIKE 'TABLE_NAME'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt->fetch();
$number_of_rows_before = $row['Rows'];
// Do your query here, afterwards
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt->fetch();
$number_of_rows_after = $row['Rows'];
// If condition
if($number_of_rows_before == $number_of_rows_after) // Update was executed
else // a new row was inserted.
Just use mysqli_affected_rows,it returns the number of rows affected by the last INSERT, UPDATE, REPLACE or DELETE query.
From PHP documentation:
In the case of "INSERT ... ON DUPLICATE KEY UPDATE" queries, the return value will be 1 if an insert was performed, or 2 for an update of an existing row.
see https://www.php.net/manual/en/function.mysql-affected-rows.php
From Mysql manual:
"With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
the row is inserted as a new row and 2 if an existing row is updated."
See: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
This is the most reliable way to do it.
maybe you put the answer right into the query like:
INSERT INTO table (col1,col2, col_type) VALUES ('1','2','inserted')
ON DUPLICATE KEY UPDATE col1 = '1', col2 = '2', col_type = 'updated'

How do you add the id of one record into a column on another record?

If I have two different MySQL insert functions in a document going to two different tables, how can I get the id of one record and place it in the other table?
After the first insert you can pickup the id via mysql_insert_id
tru something like this
function insert1()
{
mysql_query("INSERT .....");
return myqsl_insert_id();
}
function insert2()
{
$id1 = insert1(); // the id you want
mysql_query("INSERT ..... $id1 ");
}
you can get the last insert id by mysql_insert_id() function and then use it.
For example your first Insert query is
$insertqry1 = mysql_query("insert into tbl_name values(..,...,..)");
$lastinsertid = myqsl_insert_id();
Your second Query will be
$insertqry2 = mysql_query("insert into tbl_name(id) values('$lastinsertid')");

How do I get all the ids of the row created by one multiple row insert statement

I'm new to php. So, please forgive me if this seems like a dumb question.
Say i have a MySQL insert statement insert into table (a,b) values (1,2),(3,4),(5,6). table 'table' has a auto increment field called 'id'.
how can I retrieve all the ids created by the insert statement above?
It will be great if i get an example that uses mysqli.
You can't. I would suggest that you maintain your own ids (using guid or your own auto-increment table) and use it when you insert into the table.
But it's possible to get the auto-increment value for the last inserted using LAST_INSERT_ID():
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
AngeDeLaMort's answer is almost right. Certainly, the most appropriate way to deal with the problem is to insert one row at a time and poll the insert_id or generate the sequence elsewhere (which has additional benefits in terms of scalability).
I'd advise strongly against trying to determine the last insert_id and comparing this the most recent insert_id after the insert - there's just too may ways this will fail.
But...an alternative approach would be:
....
"INSERT INTO destn (id, data, other, trans_ref)
SELECT id, data, other, connection_id() FROM source";
....
"SELECT id FROM destn WHERE trans_ref=connection_id()";
....
"UPDATE destn SET trans_ref=NULL where trans_ref=connection_id()";
The second query will return the ids generated (note that this assumes that you use the same connection for all 3 queries). The third query is necessary because connection ids to go back into the pool when you disconnect (i.e. are reused).
C.
In some cases, if you have another identifier of sort such as a UserID, you could filter your query by UniqueID's greater than or equal to mysql_insert_id(), limit by the number of affected rows and only display those by the user. This would really only work inside of a transaction.
$SQL = "INSERT INTO Table
(UserID, Data)
VALUES
(1,'Foo'),
(1,'Bar'),
(1,'FooBar')";
$Result = mysql_query($SQL);
$LastID = mysql_insert_id();
$RowsAffected = mysql_affected_rows();
$IDSQL = "SELECT RecordID
FROM Table
WHERE UserID = 1
AND RecordID >= '$LastID'
LIMIT '$RowsAffected'";
$IDResult = mysql_query($IDSQL);
as a follow up to AngeDeLaMort:
You could seperate your inserts and do it something like this:
$data = array (
array(1,2),
array(3,4),
array(5,6)
);
$ids = array();
foreach ($data as $item) {
$sql = 'insert into table (a,b) values ('.$item[0].','.$item[1].')';
mysql_query ($sql);
$id[] = mysql_insert_id();
}
Now all your new id's are in the $id array.
Maybe I can do this
$insert = "insert into table (a,b) values (1,2),(3,4),(5,6)";
$mysqli->query($insert);
$rows_to_be_inserted=3;
$inserted_id = $mysqli->insert_id // gives me the id of the first row in my list
$last_row_id = ($inserted_id+$rows_to_be_inserted)-1;
$mysql->query("select * from table where id between $inserted_id and $last_row_id");
what to you guys say?

Categories