Authentication Services
Command Line Specific Extensions
Compression and Archive Extensions
Cryptography Extensions
Database Extensions
Date and Time Related Extensions
File System Related Extensions
Human Language and Character Encoding Support
Image Processing and Generation
Mail Related Extensions
Mathematical Extensions
Non-Text MIME Output
Process Control Extensions
Other Basic Extensions
Other Services
Search Engine Extensions
Server Specific Extensions
Session Extensions
Text Processing
Variable and Type Related Extensions
Web Services
Windows Only Extensions
XML Manipulation
GUI Extensions
Keyboard Shortcuts
?
This help
Next menu item
Previous menu item
Previous man page
Next man page
Scroll to bottom
Scroll to top
Goto homepage
Goto search
(current page)
Focus search box
使用
LAST_INSERT_ID()
MySQL 函数执行
INSERT
或
UPDATE
语句也会修改
mysqli_insert_id()
返回的值。如果使用
LAST_INSERT_ID(expr)
生成
AUTO_INCREMENT
的值,将返回最后
expr
的值而不是生成的
AUTO_INCREMENT
值。
如果之前的语句没有修改
AUTO_INCREMENT
的值,则返回
0
。
mysqli_insert_id()
必须在生成值的语句之后立即调用。
<?php
mysqli_report
(
MYSQLI_REPORT_ERROR
|
MYSQLI_REPORT_STRICT
);
$mysqli
= new
mysqli
(
"localhost"
,
"my_user"
,
"my_password"
,
"world"
);
$mysqli
->
query
(
"CREATE TABLE myCity LIKE City"
);
$query
=
"INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)"
;
$mysqli
->
query
(
$query
);
printf
(
"New record has ID %d.\n"
,
$mysqli
->
insert_id
);
/* 删除表 */
$mysqli
->
query
(
"DROP TABLE myCity"
);
<?php
mysqli_report
(
MYSQLI_REPORT_ERROR
|
MYSQLI_REPORT_STRICT
);
$link
=
mysqli_connect
(
"localhost"
,
"my_user"
,
"my_password"
,
"world"
);
mysqli_query
(
$link
,
"CREATE TABLE myCity LIKE City"
);
$query
=
"INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)"
;
mysqli_query
(
$link
,
$query
);
printf
(
"New record has ID %d.\n"
,
mysqli_insert_id
(
$link
));
/* 删除表 */
mysqli_query
(
$link
,
"DROP TABLE myCity"
);
I have received many statements that the insert_id property has a bug because it "works sometimes". Keep in mind that when using the OOP approach, the actual instantiation of the mysqli class will hold the insert_id.
The following code will return nothing.
<?php
$mysqli
= new
mysqli
(
'host'
,
'user'
,
'pass'
,
'db'
);
if (
$result
=
$mysqli
->
query
(
"INSERT INTO t (field) VALUES ('value');"
)) {
echo
'The ID is: '
.
$result
->
insert_id
;
}
?>
This is because the insert_id property doesn't belong to the result, but rather the actual mysqli class. This would work:
<?php
$mysqli
= new
mysqli
(
'host'
,
'user'
,
'pass'
,
'db'
);
if (
$result
=
$mysqli
->
query
(
"INSERT INTO t (field) VALUES ('value');"
)) {
echo
'The ID is: '
.
$mysqli
->
insert_id
;
}
?>
There has been no examples with prepared statements yet.
```php
$u_name = "John Doe";
$u_email = "johndoe@example.com";
$stmt = $connection->prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->bind_param('ss', $u_name, $u_email);
$stmt->execute();
echo $stmt->insert_id;
```
For UPDATE you simply change query string and binding parameters accordingly, the rest stays the same.
Of course the table needs to have AUTOINCREMENT PRIMARY KEY.
Watch out for the oo-style use of $db->insert_id. When the insert_id exceeds 2^31 (2147483648) fetching the insert id renders a wrong, too large number. You better use the procedural mysqli_insert_id( $db ) instead.
[EDIT by danbrown AT php DOT net: This is another prime example of the limits of 32-bit signed integers.]
When running extended inserts on a table with an AUTO_INCREMENT field, the value of mysqli_insert_id() will equal the value of the *first* row inserted, not the last, as you might expect.
<?
//mytable has an auto_increment field
$db->query("INSERT INTO mytable (field1,field2,field3) VALUES ('val1','val2','val3'),
('val1','val2','val3'),
('val1','val2','val3')");
echo $db->insert_id; //will echo the id of the FIRST row inserted
?>
If you try to INSERT a row using ON DUPLICATE KEY UPDATE, be aware that insert_id will not update if the ON DUPLICATE KEY UPDATE clause was triggered.
When you think about it, it's actually very logical since ON DUPLICATE KEY UPDATE is an UPDATE statement, and not an INSERT.
In a worst case scenario, if you're iterating over something and doing INSERTs while relying on insert_id in later code, you could be pointing at the wrong row on iterations where ON DUPLICATE KEY UPDATE is triggered!
What is unclear is how concurrency control affects this function. When you make two successive calls to mysql where the result of the second depends on the first, another user may have done an insert in the meantime.
The documentation is silent on this, so I always determine the value of an auto increment before and after an insert to guard against this.
The example is lack of insert_id in multi_query. Here is my example:
Assuming you have a new test_db in mysql like this:
create database if not exists test_db;
use test_db;
create table user_info (_id serial, name varchar(100) not null);
create table house_info (_id serial, address varchar(100) not null);
Then you run a php file like this:
<?php
define
(
'SERVER'
,
'127.0.01'
);
define
(
'MYSQL_USER'
,
'your_user_name'
);
define
(
'MYSQL_PASSWORD'
,
'your_password'
);
$db
= new
mysqli
(
SERVER
,
MYSQL_USER
,
MYSQL_PASSWORD
,
"test_db"
,
3306
);
if (
$db
->
connect_errno
)
echo
"create db failed, error is "
,
$db
->
connect_error
;
else {
$sql
=
"insert into user_info "
.
"(name) values "
.
"('owen'), ('john'), ('lily')"
;
if (!
$result
=
$db
->
query
(
$sql
))
echo
"insert failed, error: "
,
$db
->
error
;
else
echo
"last insert id in query is "
,
$db
->
insert_id
,
"\n"
;
$sql
=
"insert into user_info"
.
"(name) values "
.
"('jim');"
;
$sql
.=
"insert into house_info "
.
"(address) values "
.
"('shenyang')"
;
if (!
$db
->
multi_query
(
$sql
))
echo
"insert failed in multi_query, error: "
,
$db
->
error
;
else {
echo
"last insert id in first multi_query is "
,
$db
->
insert_id
,
"\n"
;
if (
$db
->
more_results
() &&
$db
->
next_result
())
echo
"last insert id in second multi_query is "
,
$db
->
insert_id
,
"\n"
;
else
echo
"insert failed in multi_query, second query error is "
,
$db
->
error
;
}
$db
->
close
();
}
?>
You will get output like this:
last insert id in query is 1
last insert id in first multi_query is 4
last insert id in second multi_query is 1
Conclusion:
1 insert_id works in multi_query
2 insert_id is the first id mysql has used if you have insert multi values
msqli_insert_id();
This seems to return that last id entered.
BUT, if you have multiple users running the same code, depending on the server or processor I have seen it return the wrong id.
Test Case:
Two users added an item to their list.
I have had a few times where the id was the id from the other user.
This is very very rare and it only happens on my test server and not my main server.
I am guessing it is because of multicores (maybe hyperthreading) or how the operating system handles multi-threads.
It is rare, but it happens.