ChatGPT解决这个技术问题 Extra ChatGPT

PHP/MySQL insert row then get 'id'

The 'id' field of my table auto increases when I insert a row. I want to insert a row and then get that ID.

I would do it just as I said it, but is there a way I can do it without worrying about the time between inserting the row and getting the id?

I know I can query the database for the row that matches the information that was entered, but there is a high change there will be duplicates, with the only difference being the id.


T
Top-Master
$link = mysqli_connect('127.0.0.1', 'my_user', 'my_pass', 'my_db');
mysqli_query($link, "INSERT INTO mytable (1, 2, 3, 'blah')");
$id = mysqli_insert_id($link);

See mysqli_insert_id().

Whatever you do, don't insert and then do a "SELECT MAX(id) FROM mytable". Like you say, it's a race condition and there's no need. mysqli_insert_id() already has this functionality.

Another way would be to run both queries in one go, and using MySQL's LAST_INSERT_ID() method, where both tables get modified at once (and PHP does not need any ID), like:

mysqli_query($link, "INSERT INTO my_user_table ...;
  INSERT INTO my_other_table (`user_id`) VALUES (LAST_INSERT_ID())");

Note that Each connection keeps track of ID separately (so, conflicts are prevented already).


The PDO equivalent is PDO::lastInsertId (us3.php.net/manual/en/pdo.lastinsertid.php).
Does it still works if there will 10000 async inserts at the same time?
@zie1ony Yes, it would work for a million async inserts because MySQL is ACID compliant. Each individual insert from the many async inserts is within its own isolated session, which is where the ID comes from when you call mysql_insert_id() from your PHP (or LAST_INSERT_ID() in MySQL)
On the doc there is something to note: mysql_insert_id() will convert the return type of the native MySQL C API function mysql_insert_id() to a type of long (named int in PHP). If your AUTO_INCREMENT column has a column type of BIGINT (64 bits) the conversion may result in an incorrect value. Instead, use the internal MySQL SQL function LAST_INSERT_ID() in an SQL query. For more information about PHP's maximum integer values, please see the integer documentation.\
need to rewrite everything i've ever written -_-
P
Peter Mortensen

The MySQL function LAST_INSERT_ID() does just what you need: it retrieves the id that was inserted during this session. So it is safe to use, even if there are other processes (other people calling the exact same script, for example) inserting values into the same table.

The PHP function mysql_insert_id() does the same as calling SELECT LAST_INSERT_ID() with mysql_query().


NB echo mysql_insert_id(); mysql_query('SELECT LAST_INSERT_ID(600)'); echo mysql_insert_id(); mysql_query('SELECT LAST_INSERT_ID()'); The second mysql_insert_id() doesn't reflect 600, where as mysql_query('SELECT LAST_INSERT_ID()') will. To get the mysql_insert_id() to reflect the change you have to first do an insert or an update (which can affect 0 rows). See very last paragraph of:http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
N
NaturalBornCamper

As to PHP's website, mysql_insert_id is now deprecated and we must use either PDO or MySQLi (See @Luke's answer for MySQLi). To do this with PDO, proceed as following:

$db = new PDO('mysql:dbname=database;host=localhost', 'user', 'pass');
$statement = $db->prepare('INSERT INTO people(name, city) VALUES(:name, :city)');
$statement->execute([':name' => 'Bob', ':city' => 'Montreal']);

echo $db->lastInsertId();

We have the option to use either PDO or MySQLi (which I describe in another answer here). A good comparison: code.tutsplus.com/tutorials/…
L
Luke

As @NaturalBornCamper said, mysql_insert_id is now deprecated and should not be used. The options are now to use either PDO or mysqli. NaturalBornCamper explained PDO in his answer, so I'll show how to do it with MySQLi (MySQL Improved) using mysqli_insert_id.

// First, connect to your database with the usual info...
$db = new mysqli($hostname, $username, $password, $databaseName);
// Let's assume we have a table called 'people' which has a column
// called 'people_id' which is the PK and is auto-incremented...
$db->query("INSERT INTO people (people_name) VALUES ('Mr. X')");
// We've now entered in a new row, which has automatically been 
// given a new people_id. We can get it simply with:
$lastInsertedPeopleId = $db->insert_id;
// OR
$lastInsertedPeopleId = mysqli_insert_id($db);

Check out the PHP documentation for more examples: http://php.net/manual/en/mysqli.insert-id.php


Thanks for catching that. I really prefer Javascript's dot notation over PHP's arrow notation. :/
l
leMoisela

I just want to add a small detail concerning lastInsertId();

When entering more than one row at the time, it does not return the last Id, but the first Id of the collection of last inserts.

Consider the following example

$sql = 'INSERT INTO my_table (varNumb,userid) VALUES
     (1, :userid),
     (2, :userid)';
$sql->addNewNames = $db->prepare($sql);
addNewNames->execute(array(':userid' => $userid));

echo $db->lastInsertId();

What happens here is that I push in my_table two new rows. The id of the table is auto-increment. Here, for the same user, I add two rows with a different varNumb.

The echoed value at the end will be equal to the id of the row where varNumb=1, which means not the id of the last row, but the id of the first row that was added in the last request.


stick to one operation at a time - seems to be the overall answer for all methods used, to avoid unexpected behaviours
u
user1012181

An example.

    $query_new = "INSERT INTO students(courseid, coursename) VALUES ('', ?)";
    $query_new = $databaseConnection->prepare($query_new);
    $query_new->bind_param('s', $_POST['coursename']);
    $query_new->execute();
    $course_id = $query_new->insert_id;
    $query_new->close();

The code line $course_id = $query_new->insert_id; will display the ID of the last inserted row. Hope this helps.


M
Murali

Try like this you can get the answer:

<?php
$con=mysqli_connect("localhost","root","","new");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

mysqli_query($con,"INSERT INTO new values('nameuser','2015-09-12')");

// Print auto-generated id
echo "New record has id: " . mysqli_insert_id($con);

mysqli_close($con);
?>

Have a look at following links:

http://www.w3schools.com/php/func_mysqli_insert_id.asp

http://php.net/manual/en/function.mysql-insert-id.php

Also please have a note that this extension was deprecated in PHP 5.5 and removed in PHP 7.0


T
Tot Zam

I found an answer in the above link http://php.net/manual/en/function.mysql-insert-id.php

The answer is:

mysql_query("INSERT INTO tablename (columnname) values ('$value')");        
echo $Id=mysql_insert_id();

insecure mysql answer, never use it.
u
uriateho

Try this... it worked for me!

$sql = "INSERT INTO tablename (row_name) VALUES('$row_value')";
    if (mysqli_query($conn, $sql)) {
    $last_id = mysqli_insert_id($conn);
    $msg1 = "New record created successfully. Last inserted ID is: " . $last_id;
} else {
    $msg_error = "Error: " . $sql . "<br>" . mysqli_error($conn);
    }

n
neoSmith

Another possible answer will be:

When you define the table, with the columns and data it'll have. The column id can have the property AUTO_INCREMENT.

By this method, you don't have to worry about the id, it'll be made automatically.

For example (taken from w3schools )

CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)

Hope this will be helpful for someone.

Edit: This is only the part where you define how to generate an automatic ID, to obtain it after created, the previous answers before are right.


this is not a possible answer at all, OP already states they are using auto-increment (auto increases). OP wants to retrieve that automatically generated id.
Okay, after reading again i've noticed that the problem is not only generating the id, OP also want to get that id. Thanks for the definition :D