簡體   English   中英

mysql_insert_id和last_insert_id錯誤的行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM