2011-09-07 151 views
44

通常我可以插入一行到一個MySQL表,並獲得last_insert_id回來。但是,現在我想批量插入表中的許多行並獲取一個ID數組。有誰知道我該怎麼做?如何將多行插入到MySQL表中並返回新ID?

有一些類似的問題,但它們並不完全一樣。我不想將新ID插入任何臨時表;我只想取回ID數組。

Can I retrieve the lastInsertId from a bulk insert?

Mysql mulitple row insert-select statement with last_insert_id()

+0

爲什麼你不能一個一個插入它們? – sanmai

+0

你需要模擬'OUTPUT'子句。我相信你可以在MySQL中使用觸發器來做到這一點 –

+0

你不能使用批量插入,然後函數石灰last_insert_id(),它不起作用。 –

回答

41

舊的線程,但只是看看這個,所以在這裏:如果您在最新版本的MySQL上使用InnoDB,您可以使用LAST_INSERT_ID()和ROW_COUNT()獲取ID列表。做批量插入時

InnoDB的保證了自動遞增的順序號,提供innodb_autoinc_lock_mode被設置爲0(傳統)或1(連續的)。 因此你可以通過添加ROW_COUNT()得到LAST_INSERT_ID()的第一 ID和最後 - 1。

+2

你需要交易嗎?如果其他刀片進入中間怎麼辦? – Mark

+3

只要您使用InnoDB引擎並確保啓用了auto_increment鎖定(這可能導致性能降低),則不需要明確的事務定義。由於InnoDB在插入過程中執行鎖定,所以其他插入必須等待插入完成。看看http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html –

+0

MYISAM呢? – CMCDragonkai

9

我能想到這是可以做到的唯一方法是,如果你存儲每個組行插入(GUID) 然後選擇行ID的唯一標識符。 如:

INSERT INTO t1 
(SELECT col1,col2,col3,'3aee88e2-a981-1027-a396-84f02afe7c70' FROM a_very_large_table); 
COMMIT; 

SELECT id FROM t1 
WHERE guid='3aee88e2-a981-1027-a396-84f02afe7c70'; 

你也可以生成使用uuid()

-8
$query = "INSERT INTO TABLE (ID,NAME,EMAIL) VALUES (NULL,VALUE1, VALUE2)"; 
$idArray = array(); 
foreach($array as $key) { 
mysql_query($query); 
array_push($idArray, mysql_insert_id()); 
} 
print_r($idArray); 
+2

它不是批量插入查詢。 – Peacemoon

0

的全局唯一標識符在數據庫中,我認爲你將不得不自行處理事務ID在你的應用程序,或項目ID在你的應用程序以完美無瑕地執行此操作。 (!),這樣做可能工作,假設所有的刀片成功

的一種方式,如下:

然後,您可以獲取插入的ID與受影響的行數,從一環lastid(這是批量插入的第一個插入ID)。 就這樣,我檢查它完美..只是要小心,HeidiSQL例如將不返回ROW_COUNT()的正確值,可能是因爲它是一個蹩腳的GUI做隨機狗屎,我們不問它 - 但它是從完全正確的命令行或PHP的mysqli -

START TRANSACTION; 
BEGIN; 
INSERT into test (b) VALUES ('1'),('2'),('3'); 
SELECT LAST_INSERT_ID() AS lastid,ROW_COUNT() AS rowcount; 
COMMIT; 

在PHP它看起來像這樣(local_sqle是mysqli_query直呼叫,local_sqlec是調用mysqli_query +轉換結果集到PHP數組):

local_sqle("START TRANSACTION; 
BEGIN; 
INSERT into test (b) VALUES ('1'),('2'),('3');"); 
$r=local_sqlec("SELECT LAST_INSERT_ID() AS lastid,ROW_COUNT() AS rowcount;"); 
local_sqle(" 
COMMIT;"); 
$i=0; 
echo "last id =".($r[0]['lastid'])."<br>"; 
echo "Row count =".($r[0]['rowcount'])."<br>"; 

while($i<$r[0]['rowcount']){ 
    echo "inserted id =".($r[0]['lastid']+$i)."<br>"; 
    $i++; 
} 

查詢分開的原因是因爲我不會使用我自己的函數得到我的結果,如果喲你用標準函數做這件事,你可以把它放回到一個語句中,然後檢索你需要的結果(它應該是結果2號 - 假設你使用了一個處理多個結果集/查詢的擴展)。

1

讓我們假設我們有一個名爲不是Temptable有兩個的cols UID,COL1其中uid是一個自動增量字段的表。做下面的操作將返回結果集中所有插入的ID。你可以遍歷結果集並獲取你的id。我意識到這是一箇舊帖子,這種解決方案可能不適用於每一種情況。但對於其他人而言,這可能是我爲什麼回覆它的原因。

# lock the table 
lock tables temptable write; 

#bulk insert the rows; 
insert into temptable(col1) values(1),(2),(3),(4); 

#get the value of first inserted row. when bulk inserting last_insert_id() #should give the value of first inserted row from bulk op. 
set @first_id = last_insert_id(); 

#now select the auto increment field whose value is greater than equal to #the first row. Remember since you have write lock on that table other #sessions can't write to it. This resultset should have all the inserted #id's 
select uid from temptable where uid >[email protected]_id; 

#now that you are done don't forget to unlock the table. 
unlock tables; 
相關問題