2011-09-07 148 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; 
相关问题