[英]mysql_insert_id and last_insert_id wrong behavior
我有這張桌子
CREATE TABLE IF NOT EXISTS `t5` (
`id` int(11) NOT NULL auto_increment,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `a` (`a`,`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
a_b是唯一的密鑰。
我有這樣的PHP代碼
$db = DBFactory::getInstance();
$db->selectDB('test');
$db->query("insert into t5 (a, b) values(1, 1) on duplicate key update a=1, b=1");
var_dump(mysql_insert_id());
$cur = $db->query("select last_insert_id()");
var_dump(mysql_fetch_assoc($cur));
通過運行此代碼兩次,在我的電腦上結果是第1
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "1"
}
第2
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "2"
}
你可以看到,兩次mysql_insert_id()返回相同的值“1”,這對我來說沒問題,因為我想知道插入后的真實id,而不是下一個auto_increment值。
但是,當我在另一個環境中運行此代碼兩次時:第1次
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "1"
}
第2
int(2)
array(1) {
["last_insert_id()"]=>
string(1) "2"
}
正如您所看到的那樣,第二次的結果mysql_insert_id()返回與last_insert_id()相同的值。
這個結果太可怕了,但我不知道為什么。 我的代碼在這兩種環境中運行良好約3個月,直到今天才發生這種情況。 誰能解釋一下? 我在大約30天前將第二個環境的PHP版本升級到5.3.8,沒有其他更改。 這是一個錯誤嗎?
更新
我切換到第三個mysql服務器(5.1.38-log),第二個插入返回int(0)數組(1){[“last_insert_id()”] => string(1)“0”}
所以我意識到問題可能是關於mysql版本。
最后,我將表定義更改為此
DROP TABLE IF EXISTS `t5`;
CREATE TABLE IF NOT EXISTS `t5` (
`id` int(11) NOT NULL auto_increment,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`t` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `a` (`a`,`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
還要編輯我的腳本
$db = DBFactory::getInstance();
$db->selectDB('test');
$db->query("insert into t5 (a, b, t) values(1, 1, ".time().") on duplicate key update a=1, b=1, t=".time());
//$db->query("insert ignore into t5 (a, b) values(1, 1)");
var_dump(mysql_insert_id());
$cur = $db->query("select last_insert_id()");
var_dump(mysql_fetch_assoc($cur));
不同的mysql服務器返回相同的mysql_insert_id但不同的last_insert_id()
5.0.24a社區-NT
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "2"
}
5.0.51a日志
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "2"
}
5.1.38日志
int(1)
array(1) {
["last_insert_id()"]=>
string(1) "0"
}
是否有任何系統變量控制此行為? 如果有人知道那會很有意思。 如果沒有解決方案,我唯一能做的就是強制這樣插入來更新一些具有不同值的字段......
我認為你試圖使用last_insert_id()
是不可能的 - 在這種情況下你沒有插入任何東西,所以你也不應該信任返回值。 來自MySQL文檔 :
如果表包含AUTO_INCREMENT列並且INSERT ... UPDATE插入行,則LAST_INSERT_ID()函數返回AUTO_INCREMENT值。 如果語句更新了一行,則LAST_INSERT_ID()沒有意義。
但是,似乎有一個解決方法(相同的文檔) - 手動設置last_insert_id:
但是,您可以使用LAST_INSERT_ID(expr)解決此問題。 假設id是AUTO_INCREMENT列。 要使LAST_INSERT_ID()對更新有意義,請按如下方式插入行:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.