PHP Doku:: Liefert die ID einer vorherigen INSERT-Operation - function.mysql-insert-id.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzDatenbankerweiterungenAnbieterspezifische DatenbankerweiterungenMySQLMySQL Funktionenmysql_insert_id

Ein Service von Reinhard Neidl - Webprogrammierung.

MySQL Funktionen

<<mysql_info

mysql_list_dbs>>

mysql_insert_id

(PHP 4, PHP 5)

mysql_insert_id Liefert die ID einer vorherigen INSERT-Operation

Beschreibung

int mysql_insert_id ([ resource $Verbindungs-Kennung ] )

mysql_insert_id() liefert die ID, die bei der letzten INSERT-Operation für ein Feld vom Typ AUTO_INCREMENT vergeben wurde. Wenn die Verbindungs-Kennung nicht angegeben wird, wird die zuletzt geöffnete Verbindung angenommen.

mysql_insert_id() liefert 0, wenn die vorhergehende Abfrage keinen AUTO_INCREMENT Wert erzeugt hat. Falls Sie den Wert zur späteren Verwendung speichern möchten, stellen Sie sicher, dass Sie mysql_insert_id() direkt nach der Abfrage aufrufen, die einen Wert erzeugt hat.

Hinweis:

Der Wert der MySQL SQL Funktion LAST_INSERT_ID() liefert immer den zuletzt erzeugten AUTO_INCREMENT Wert. Dieser wird zwischen Abfragen nicht zurückgesetzt.

Warnung

mysql_insert_id() konvertiert den Typ der Rückgabe der nativen MySQL C API Funktion mysql_insert_id() in den Typ long (als int in PHP bezeichnet). Falls Ihre AUTO_INCREMENT Spalte vom Typ BIGINT ist, ist der Wert den mysql_insert_id() liefert, nicht korrekt. Verwenden Sie in diesem Fall stattdessen die MySQL interne SQL Funktion LAST_INSERT_ID() in einer SQL-Abfrage.

Beispiel #1 mysql_insert_id() Beispiel

<?php
mysql_connect
("localhost""mysql_user""mysql_password")
    or die(
": " mysql_error());
mysql_select_db("mydb");

mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf (" %d\n"mysql_insert_id());
?>
<?php
$link 
mysql_connect('localhost''mysql_user''mysql_password');
if (!
$link) {
    die(
'Keine Verbindung möglich: ' mysql_error());
}
mysql_select_db('mydb');

mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf("Der zuletzt eingefügte Datensatz hat die ID %d\n"mysql_insert_id());
?>

Siehe auch mysql_query() und mysql_info().


52 BenutzerBeiträge:
- Beiträge aktualisieren...
jayon
7.04.2010 15:01
if trying to insert a generated random id use mysql's UUID() to generate a unique key for you, there should be a lot less problems with it.

<?php
$query
= sprintf( "INSERT INTO `users`"
   
."(`id`    ,`username`)"
   
."VALUES"
   
."(UUID(),'%s'           )",
   
mysql_real_escape_string($user)
  );

if( !
mysql_query($query) )
{
/*insert failed*/}

$id = mysql_insert_id();
?>
dave
11.01.2010 7:19
There is a lot of incorrect info here on "don't use AI" and "using max is equivalent".  Then you have people improperly advising you to use psuedo-random numbers

If you're really worried about the AI field not returning because of the inherent race conditions, just do a select statement based on the vars you just input.  If your vars are not unique, DON'T use these psuedo-random numbers.  When you have enough iterations, the probability that the one of these randoms becomes a duplicate gets pretty high.

Instead, just use the unix timestamp.  However, don't use UNIX_TIMESTAMP() in your query, because if you do, when you run your select statement right after, there's a possibility that you'll end up with a different timestamp.

Since date() continues to count up during the execution of the script, simply store date(U) into a variable or definition.  Then insert and select based on that.  Assuming you're not using mysql procedures:

<?php
define
(UNIX_TIMESTAMP, date('U'));
$db->query("insert into table values('', 'a', 'b', 'c', 'd', '".UNIX_TIMESTAMP."'");
$res = $db->query("select id from table where a_col = 'a' and b_col = 'b' and c_col = 'c' and d_col = 'd' and temp_id = 'UNIX_TIMESTAMP'");
...
?>
mmurphy at cpmsnational dot com
9.11.2009 20:18
If mysql_insert_id() returns 0 or null, check that you have also included the link identifier. It is optional but if you have more than one database connection then this is necessary.

ex: mysql_insert_id($conn)
bargainbatman at gmail dot com
25.09.2009 15:16
I thought this would be relevant to all the people using mysqli and looking for the ID after INSERT command :

<?php
function insert_join($catid, $disc_id) {
// insert a new item into the database
  
$conn = db_connect();
  
// insert new item
  
$demande = "insert into categories_disc values ('', '".$catid."', '".$disc_id."')";
  
$resultat = $conn->query($demande);
   if (!
$resultat) {
     return
false;
   } else {
    return
$conn->insert_id; // function will now return the ID instead of true.
}

}
?>

Then, on the other side, let us call this function as follows :

<?php
$cat_id
= insert_join($catid, $disc_id);
if(
$cat_id !== false) {
   
        echo
"<p>Category stuff was added to the database as follows : <br>";
        echo
"<hr>ID de la category : ".$cat_id."</p><hr>";

        }
?>
RPaseur at NationalPres dot org
18.09.2009 20:48
Apparently the value returned by mysql_insert_id() may be correct for BIGINT auto_increment keys below the value of INT, but it may wrap to negative when the BIGINT auto_increment passes the largest signed value of INT.  A timebomb for very large tables...

PHP 5.2.10, MySQL 5.0.81, assume the connection and selection...

<?php
// CREATE A TABLE AND ALTER IT TO A HIGH INDEX NUMBER
$sql = "CREATE TEMPORARY TABLE noise ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ) ENGINE=MEMORY";
if (!
$res = mysql_query($sql)) die(mysql_error());

$sql = "ALTER TABLE noise AUTO_INCREMENT = 2147483646";
if (!
$res = mysql_query($sql)) die(mysql_error());

// INSERT DATA TO ADD TO THE AUTO_INCREMENT INDEX
$kount = 0;
while (
$kount < 3)
{
  
$sql = "INSERT INTO noise () VALUES ()";
   if (!
$res = mysql_query($sql)) die(mysql_error());
  
$nid = mysql_insert_id($dbcx);
  
var_dump($nid);
  
$kount++;
}

// PRODUCES THIS
// int(2147483646)
// int(2147483647)
// int(-2147483648)
?>
Ultimater at gmail dot com
18.05.2009 14:53
Here's an elegant way to INSERT using UPDATE syntax.

<?php
function insert_update($table,$fields,$id=NULL)
{
    if(
$id===NULL)
    {
       
$sql="INSERT INTO $table (id) VALUES(NULL);UPDATE $table SET $fields WHERE id = LAST_INSERT_ID()";
    }else{
       
$sql="UPDATE $table SET $fields WHERE id = $id";
    }
    return
$sql;
}
?>

Usage:

<?php
$table
="`members`";
$fields="`username` = 'Ultimater',`userlevel` = 'member'";
if(!
$profile_exists)
{
//insert a record
   
$sql=insert_update($table,$fields);
   
mysql_query($sql);
}else{
//update a record
   
$sql=insert_update($table,$fields,5);
   
mysql_query($sql);
}
?>
Anonymous
22.07.2008 11:25
If i can't get a good increment.
I use this function

<?php
function get_new_id($table){
 
$select = 'select max(`id`) +1as `id` from `'.$table.'`  where `id` != <some big id>';
 
$query = mysql_query($select);
 
$obj = mysql_fetch_object($query);
 return
$obj->id;
}
?>
neep03 at zonnet dot nl
10.07.2008 22:52
I solved the problem by inserting a "unique" code, like md5 or session_id.
First you insert the date in de database and in the next step you look for de used id.
Just a part of the php script.

<?php
$code  
= md5(uniqid());  // a random 32 digits code is generated
$name   = $POST_[name];
$email  = $POST_[email];

// first step
$mysql_id = mysql_connect("$dbhost","$dbuser","$dbpass");
$sql = "INSERT into database (code,name,email) VALUES('$code','$name','$email')";
$res = mysql_db_query("$db","$sql",$mysql_id);

     include(
"error.php");

//second step
$mysql_id = mysql_connect("$dbhost","$dbuser","$dbpass");
$sql = "select * from database where code='$code' "// select the record with the above generated md5 code
$res = mysql_db_query("$db","$sql",$mysql_id);

     include(
"error.php");

$row = mysql_fetch_row($res);

$id = $row[0]; // this is de used id genereted by auto_increment for this input
?>
thomas at tgohome dot com
6.07.2008 22:47
Be careful, because this operates on the last performed query, it includes UPDATEs and SELECTs as 'queries'. For example, this is what I set up.

INSERT post into database
UPDATE child forums with insert ID (insert ID is correct)
Insert ID = 0 because of last query
Send the user to their post - but fail because the insert ID is zero.

So store it in a variable like $insert_id instead of querying it every time.
icethenet at NOSPAM dot hotmail dot com
19.06.2008 22:13
Other methods seem to have problems with missing records in auto increment sometimes you will have records 1 2 5 6 most functions would return the value of 5 for next auto increment when indeed it would be 7. This is the only way I found to make this work so I can use my customer number and the record number to provide a truly unique customer number that is also useful.

$next_increment = 0;
$qShowStatus = "SHOW TABLE STATUS LIKE 'your_table'";
$qShowStatusResult = mysql_query($qShowStatus) or die(mysql_error());
$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];
echo $next_increment;

then you can do something like this
echo  $next_increment ."-". rand();

My first post: I hope this is useful to someone
erik.something@GMAIL DOT COM
15.06.2008 15:21
I have come up with an unorthodox solution for this problem. Im sure its not the fastest but its surely the safest.

In sql I have made a column to be "unique" and instead of fetching the last Id generated by auto_increment I make a random number and I store that number in the before created column. Example:

id ____ rand_nr ____ name
1  ____ 345432 ____ Richard
2  ____ 598675 ____ Joe
3  ____ 926374 ____ Patrick

This way I know exactly what number coresponds to the row inserted.
dane514 AT gmail DOT COM
31.05.2008 6:05
I may have solved the problems that a number of you have brought to everyone's attention. Here is a simple function that will always return the correct ID of the afffecting row (i.e., the row that will soon be inserted into)--no matter how many consecutive users are online and updating/inserting into the same table that you are also inserting/updating.

Retrieving the ID of the row soon-to-be-affected was imperative to my current project, and the various COUNT() solutions just did not cut it.

Use this before any insert/update statement to retrieve the ID of the row to be inserted into:

<?php
function get_current_insert_id($table)
{
   
$q = "SELECT LAST_INSERT_ID() FROM $table";
    return
mysql_num_rows(mysql_query($q)) + 1;
}
?>

It would be great to read any discussions if anyone considers this function problematic.
Anonymous
2.05.2008 12:22
"Why on earth are you all arguing about the best way to get the next auto_increment value? The whole point is that it increments automatically. The name should be a give away."

Because you need the same last id value in another table. So you need a way to identify it, in order to use it in the next query. This way its easier than using a new query to get the id like ORDER BY id DESC LIMIT 1
elinor dot hurst at REMOVETHIS dot gmail dot com
8.04.2008 16:27
I don't get all the fuss around this.

I read:
"The value of mysql_insert_id() is affected only by statements issued within the current client connection. It is not affected by statements issued by other clients."

See: http://dev.mysql.com/doc/refman/5.0/es/mysql-insert-id.html

I can't really see what's inaccurate about that.

"In the case of a multiple-row INSERT statement, mysql_insert_id() returns the first automatically generated AUTO_INCREMENT value; if no such value is generated, it returns the last last explicit value inserted into the AUTO_INCREMENT column."

I must be missing something here but why would you insert multiple rows and then only handle the last one with some favoured behaviour? You could just as well insert them one at a time and then handle each row separately with the latest id.

I can't see what's wrong with that.

However I can see what's wrong with simply using max(my_table.id_column) because of the concurrent access issues this would imply.
Alfred Nony Mouse
24.02.2008 2:33
There's nothing inherently wrong with using auto-increment fields. There's also nothing wrong with the main competetive idea, which is for the database to supply a primitive sequence of non-repeating identifiers, typically integers. This is rather like which side of the road you drive on.

The bigger problem is when people don't understand what they are doing with database access. It's like driving a car without really knowing the rules of the road. Such people wind up making bad decisions without realizing it, and then, eventually, something breaks.

Databases are complex beasts, and worth taking the time to really understand. Learn about the implications and limitations of different approaches to solving problems. Then, you will be prepared to pick a solution based on what has to work.
Anonymous
20.02.2008 17:45
Why on earth are you all arguing about the best way to get the next auto_increment value? The whole point is that it increments automatically. The name should be a give away.

Don't calculate the next id, just leave the field blank and let the database issue the id itself.
venimus at gmail dot com
15.02.2008 0:27
To get the most accurate NEXT auto_increment id use this function

<?php
function mysql_next_id($table) {
   
$result = mysql_query('SHOW TABLE STATUS LIKE "'.$table.'"');
   
$rows = mysql_fetch_assoc($result);
    return
$rows['auto_increment'];
}
?>

Any other methods of predicting the next autogenerated id will fail in certain cases.
Most of the programmers try to get the MAX(id)+1 (or sort the table backwards and get the first id) but this will cease to work when you delete the last record.

However in a race condition even this function may fail if other users insert records in the time between calling this function and using the return value. You may use LOCK TABLES to prevent such a case.

Anyway, the best advice I can give you is to RECONSIDER YOUR LOGIC TO AVOID USING AUTO_INCREMENT.
venimus at gmail dot com
14.02.2008 16:11
Using 'SELECT MAX(id)+1...' will not return the next auto_increment id. This function is totaly unreliable by two reasons.
1. In race conditions there is no guarantee that other user will not insert new record while your function have done its work. This will render your "generated" last_id obsolete. It is rare case but it happens.
2. Most of all, if the last record(s) in the table is deleted the max id will no longer match the auto_increment value, because auto_increment never repeats numbers, it increases whenever an insert statement is completed and does not decrease if you erase the last record!!!

e.g. If you have this table with the last record deleted:
id name
1. car
2. plane
3. truck - [erased]

auto_increment is 4
but MAX(id) is 2!!!
benfoldsforever
12.10.2007 5:04
Just wanted to re-iterate previous comment on receiving NULL or 0 return statement from calling mysql_insert_id() after insert statement.

If you have multiple mysql connections (i.e. mysql_connect() or mysqli_connect()) on the page you will need to specify the the connection you are using when calling this function!

I.e.
mysql_insert_id($MY_CONN);
bonatoque at yahoo.com
20.09.2007 22:13
It seems that, in case of a very first INSERT, mysql_insert_id() returns 0. My guess is that MySQL does not trigger auto increment if the table is empty. Once an entry is present, it works as expected.
louis at intoplay dot com
13.08.2007 16:53
If mysql_insert_id() returns 0 or null, check your auto increment field is not being set by your sql query, also if you have multiple db connections like I did, the solution is to create a seperate db connection for this query.
foros (_AT_) anthalia.com
31.07.2007 23:06
Forget about using MAX to get the last inserted id. Race conditions like other users inserting between your SELECT MAX(.. and your INSERT may render your id unusable.

The WAY to get the id is by using mysql_insert_id() or the mysql SQL function LAST_INSERT_ID().

Take care, if using mysql_insert_id() you should provide the resource returned by the mysql_connect, not the resultset returned by mysql_query.
guelphdad at yahoo dot com
18.07.2007 17:35
and the primary reason to use neither of those last two solutions is both could result in race conditions when there is more than a single user with access to the database. when you use MAX or ORDER BY DESC LIMIT 1 you will retrieve the maximum value from the table, at that moment. That doesn't mean another user doesn't do an insertion in the primary and secondary table BEFORE you do your insertion in the secondary table. You have thus inserted a row with a correct id into the second table. Always use last_insert_id()
daiguo
5.07.2007 15:43
To: Ben AT alfreido.com

<?php
function previous_id($table, $id_column) {
  if (
$table && $id_column) {
   
$result = mysql_query("SELECT MAX(".$id_column.") AS maxid FROM ".$table);
   
$stuff = mysql_fetch_assoc($result);
    return
$stuff['maxid'];
  } else {
    return
false;
  }
}
?>

Use MySQL's built-in function MAX(). It's faster because any min/max algorithm is faster than sorting entire table.
Ben AT alfreido.com
14.06.2007 5:58
I realise this isn't the best way of doing it, but if use auto_increment in your tables, which just increases by one every time you add a row, you can get the last used id simply by quering the database, selecting the id column and ordering it descendingly and pulling out the first row returned. The added bonus is you can do it anytime, instead of just after an INSERT query.

<?php
function previous_id($table, $id_column) {
  if (
$table && $id_column) {
   
$result = mysql_query("SELECT " . $id_column " FROM " . $table . "
    ORDER BY "
. $id_column . " DESC
    LIMIT 1"
);
   
$stuff = mysql_fetch_assoc($result);
    return
$stuff[$id_column];
  } else {
    return
false;
  }
}
?>

Just change $table to the table name, and $id_column to the column which auto increments.
Typer85 at gmail dot com
25.12.2006 19:44
Please be warned that this function, like almost every other MySQL function, requires that the same database resource link that was used to insert the data into the database be used to get the last auto increment value.

If you close the database connection after inserting data, then open one up again and then attempt to get the last auto increment value, you will get an incorrect value since all resources related to the last insert query were cleaned up after the connection was closed.
Bob M.
16.11.2006 19:41
There is a problem with the function below submitted by rudolflai

In that mysql_autoid function, what happens when between the time you've retrieved the id and the time you do something with it (like INSERT a new record) another new record has been inserted into the database in the interim?

Better make sure you LOCK the tables you're working on before you use the function and don't UNLOCK until after you've done something with the id returned.
buana95 att yahoo dott com
29.10.2006 10:57
It's not true that mysql_insert_id() only returns the ID generated for an AUTO_INCREMENT column by the previous INSERT query.

We can use LAST_INSERT_ID() statement that will return value for mysql_insert_id().

Example:

$sql = "UPDATE `mytable` SET `mytable_id`= LAST_INSERT_ID(`mytable_id` + 1) WHERE ...;

@mysql_query($sql);
$last_id = mysql_insert_id();

LAST_INSERT_ID() statement will affect mysql_insert_id().

Regards,
Buana
mariano at uvcms dot com
19.09.2006 18:01
When used in transactions, mysql_insert_id() MUST be called before committing. Otherwise, it will return unpredictable results.
squezy16 at hotmail dot com
17.09.2006 17:46
One of the problem of the LAST_INSERT_ID function is that it may return an old Auto_Increment number if the INSERT did not have the time to run properly while the mysql_insert_id always returns the good value. I tried to insert a row imidiatly followed by a select LAST_INSERT_ID and it kept on returning me the LAST_INSERT_ID before my insert statement.
rudolflai at gmail dot com
11.09.2006 11:59
Hi,

Below is a snippet for retriving the next insert id from a mysql table. It functions like the auto_increment option in phpMyAdmin. Hope you find it helpful. =]

<?php

function mysql_autoid($id,$table){
   
$query = 'SELECT MAX('.$id.') AS last_id FROM '.$table;
   
$result = mysql_query($query);
   
$result = mysql_fetch_array($result);
    return
$result[last_id]+1;
}

/// usage mysql_autoid('nID','news');

?>

Cheers,
Rudolf
james dot baxter at nospamplease dot com
9.05.2006 2:09
Have had many people coming to me with issues regarding last_insert_id and mysql_insert_id() etc

This is a very simple solution that caters for most. As you can see it gets the last auto inc from the field, in this case, ID.

mysql_query("LOCK TABLES art WRITE");

mysql_query("INSERT INTO table (....) VALUES (....)");

$result = mysql_query("SELECT MAX(ID) AS LAST_ID FROM table");

$result = mysql_fetch_array($result);

mysql_query("UNLOCK TABLES");

echo "Last ID#" . $result[LAST_ID];
john k.
31.01.2006 23:55
Be careful when using "insert ignore". If the unique index already exists, the record will not be added, but it WILL give you the id of the next auto_increment value even though it didn't create it.

<?php
$sql
= "insert ignore into sometable set num=10";
mysql_query($sql) or die();
echo
mysql_affected_rows()."<br>";
echo
mysql_insert_id()."<br><br>";

// same record, database is unique on 'num'
$sql = "insert ignore into sometable set num=10";
mysql_query($sql) or die();
echo
mysql_affected_rows()."<br>";
echo
mysql_insert_id()."<br><br>";
?>

would give:
1
116372

0
116373
heiligkind at yahoo dot de
14.12.2005 10:31
If you insert a data row by using the ON DUPLICATE KEY UPDATE clause in an INSERT-statement, the mysql_insert_id() function will return not the same results as if you directly use LAST_INSERT_ID() in MySQL.

See the following example:

<?
  
// insert a datarow, primary key is auto_increment
   // value is a unique key
  
$query = "INSERT INTO test (value) VALUES ('test')";
  
mysql_query( $query );

   echo
'LAST_INSERT_ID: ',
         
mysql_query( "SELECT LAST_INSERT_ID()" ),
         
'<br>mysql_insert_id: ',
         
mysql_insert_id();

?>

This will print:

LAST_INSERT_ID: 1
mysql_insert_id: 1

In this case the function returns the same as the MySQL-Statement.
But see the insert on an existing key:

<?
   $query
= "INSERT INTO test (value)
                  VALUES ('test')
                  ON DUPLICATE KEY UPDATE value = 'test2'"
;
  
mysql_query( $query );

   echo
'LAST_INSERT_ID: ',
         
mysql_query( "SELECT LAST_INSERT_ID()" ),
         
'<br>mysql_insert_id: ',
         
mysql_insert_id();

?>

This will print:

LAST_INSERT_ID: 2
mysql_insert_id: 1

By using the ON DUPLICATE KEY UPDATE clause, only the old datarow will be modified, if the INSERT statement causes a duplicate entry, but the LAST_INSERT_ID() function returns the next auto_increment value for the primary key, which is by the way not set as the next auto_increment value in the database.

The mysql_insert_id() function returns the primary key of the old (and changed) data row. For me this is the right operation method, because the LAST_INSERT_ID() function returns a value which is not referenced to a data row at all.

Greets from Munich.

heiligkind
Soroushl at gmail dot com
7.12.2005 6:53
As mentioned by frumler at the-beach dot no_spam dot net

the LAST_INSERT_ID works like a charm when inserting values into tables.

I'm not sure why anyone would need mysql_insert_id() when LAST_INSERT_ID is readily available.

example:

Say you have a table called "transaction" and a table called "accounts".  Obviously each account must be created using a transaction, so every time a record is created in the accounts table, a record must be created in the transaction table containing the same account_id(auto_increment) that was just created by mysql.

Here's a simple way to do this:

<?php
$account_query
="INSERT INTO accounts (account_id,type) VALUES (NULL,'saving')";
$transaction_query="INSERT INTO transactions(transaction_id,account_id) VALUES (NULL,LAST_INSERT_ID)";

$a_query=mysql_query($account_query);
$t_query=mysql_query($transaction_query);

?>

2.12.2005 19:48
Take care of setting an empty value for the AUTO_INCREMENT Field else you never get a value except zero returned from mysq_insert_id() ....

Ciao Ephraim
bholbrook at servillian dot com
1.09.2005 22:50
My apologies for the error below (that was modified out of a class) - as you cannot define a constant as an array.

replace the line:

<?

define
("ID",...);

?>

with

<?

$mysql_id
= mysql_query("...");

?>

$mysql_id is now an array in which the first element $mysql_id[0] holds the last inserted id.

Apologies if anyone struggled over that one... esp. the noobs.
bholbrook at servillian dot com
30.08.2005 22:45
An effective way to retrieve the last insert id without fail or having two queries inserted at the same time causing an unexpected number being returned.

<?

mysql_query
("LOCK TABLES apc_forms WRITE");
mysql_query("SET AUTOCOMMIT = 0");
mysql_query("INSERT INTO apc_forms (form_title, form_event_id, form_expirey) VALUES ('title',1,'2005-10-10')");
define('ID',mysql_query("SELECT LAST_INSERT_ID()"));
mysql_query("COMMIT");
mysql_query("UNLOCK TABLES");

?>
athies at gmail dot com
21.07.2005 23:36
Just a quick note. mysql_insert_id() does work with REPLACE.
ed at is-cool dot net
8.05.2005 19:25
Beware, mysql_insert_id() only returns the value of the last syntaxically correct insert statement.

If your code has a problem and the insert is not understood by the server then the value of the last working insert command is returned.

Put something else in place such as "select count( id ) from table" before and after the mysql_insert_id() call to ensure that a row was inserted.
relic at daimi dot au dot dk
20.02.2005 15:57
A bit more on return values:
mysql_insert_id() returns 0 if you haven't actually manipulated anything yet.

Also, it returns 0 even if the DB connection is lost[0] between inserting and calling mysql_insert_id() - so you can always count on getting an integer.

[0] By 'lost' I mean e.g. a DB crash. Actually closing the open link and then trying to communicate with the DB will of course result in an error.
brodseba AT brodseba DOT com
15.02.2005 21:37
It's possible to do the same with M$ Server.

function odbc_insert_id()
{
  $query = "SELECT @@IDENTITY AS ID;";
  $result = odbc_exec($this->m_rConnectionID, $query);
  $row = odbc_fetch_object($result);
  return $row->ID;
}
sander [ad] deltaserv [d0t] nl
11.11.2004 2:38
In reply to: sly at noiretblanc dot org:

Make sure that auto_increment has an capital A as the first letter, otherwise it WON'T work! So you have to spell it as Auto_increment... And then it works fine.
Baak
1.10.2004 8:04
I believe the "resource link" being referred to is not what is returned from mysql_query() but the $link returned from mysql_connect(). mysql_insert_id() will just use the most recent connection if there is no explicit $link being used.

So the above example in the manual page itself should behave the same with mysql_insert_id($link) at the end instead of the mysql_insert_id() they used. If you had multiple connections, the $link might come in handy.

Also in reading the mysql manual itself, there is some enlightening information on the fact that this does appear to be totally safe to use because it is on a per-connection basis.

Here's the relevant quote from the manual on LAST_INSERT_ID() which is located here: http://dev.mysql.com/doc/mysql/en/Information_functions.html

"The last ID that was generated is maintained in the server on a per-connection basis. This means the value the function returns to a given client is the most recent AUTO_INCREMENT value generated by that client. The value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that you can retrieve your own ID without concern for the activity of other clients, and without the need for locks or transactions."

Sounds safe to me. I couldn't imagine this would be done any other way *but* on a per-connection basis, otherwise chaos would ensue. The only way to test it would be to perform a multi-thread type test. Perhaps someone is up for it and wants to post their results somewhere? :)
Steve Bond
24.06.2004 20:47
If you use this function after doing an INSERT ... SELECT to insert multiple rows at once, you get the autonumber ID of the *first* row added by the INSERT.

e.g. if there are 4 records in table 'init' that have column 'type' = 2
I want to add these 4 records to table 'game'
Table game has an autonumber column 'game_id' that is currently at 32.

If I do this query:

INSERT INTO game (type, players, rounds)
SELECT type, players, rounds FROM init
WHERE type = 2

Then mysql_insert_id() will return 33, not 36.
Wayne Theisinger
26.02.2004 12:40
In response to treylane at example dot com.

It is very very very important that you put in an "or die" or some other form of error handling.

Some scripts can fail invisibly and insert invalid data throughout your whole database because of mysql_insert_id
inserting the last successful insertid rather than reporting that the last attempt failed.

example of an or die statement.

$result = mysql_query($sql)
or die("Invalid query: " . mysql_error());
$EventID = mysql_insert_id();
dtez
12.02.2004 1:36
any zerofills on your id get chopped off on this function because it returns an int.
sly at noiretblanc dot org
14.11.2003 0:29
To get the NEXT insert id use the mysql query SHOW TABLE STATUS LIKE 'tablename' and get the field auto_increment...
treylane at example dot com
24.04.2003 23:36
This might be obvious, but it tripped me up - be careful when using last_insert_id() with persistent connections - running last_insert_id() after a failed update/insert/etc will return the last insert id of the last successful update/insert made by that CONNECTION rather than 0 for the number of rows updated by the previous non-working query, and who knows what the last query run on that connection was.
jameszhou2001 at yahoo dot ca
17.12.2002 3:30
Just a reminder, mysql_insert_id() should be called after 'mysql_affected_rows()', but BEFORE 'mysql_query("COMMIT")'.
frumler at the-beach dot no_spam dot net
4.08.2001 8:17
If you want to use the ID that was generated for one table and insert it into a second table, you can use SQL statements like this:

INSERT INTO foo (auto,text)
    VALUES(NULL,'text');              # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table

...found here:
http://www.mysql.com/doc/en/Getting_unique_ID.html

It works even without inserting the NULL value for some reason ;)
The following is great for monitoring:
    $new_id = mysql_insert_id();
    print "New id: $new_id\n";

Hope it helps you all, cheers.
vksgeneric at hotmail dot com
10.12.1999 2:14
You can't do an INSERT DELAYED and expect to get anything but zero, for it runs in a separate thread, and mysql_insert_id() is tied to the current thread.
Vlad



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)