我想使用单个INSERT
语句将多行插入表中。这没有问题,因为SQL提供了为单个INSERT
语句提供多行作为参数的选项。现在,这些行包含一个ID
字段,该字段会自动递增,即其值由数据库设置,而不是由我的代码设置。
因此,我想获得插入行的ID
值。我的基本问题是:我如何为MariaDB / MySQL做到这一点?
事实证明,这很简单,例如在PostgreSQL中,因为PostgreSQL有RETURNING
clause for INSERT
,它返回一行或甚至多行的所需值。这正是我想要的,它的工作原理。
不幸的是,MariaDB和MySQL都没有PostgreSQL的RETURNING
子句,因此我需要回退到诸如LAST_INSERT_ID()
之类的东西,但这只返回最后一个插入行的ID
,即使使用单个INSERT
插入多行也是如此。如何获取所有ID
值?
我的代码目前看起来像这样:
INSERT INTO mytable
(foo, bar)
VALUES
('fooA', 'barA'),
('fooB', 'barB');
SELECT LAST_INSERT_ID() AS id;
如何以一种即使是并发写入的方式解决此问题?
(不,不是改为UUID字段的选项,或类似的东西;给出自动增量字段,不能更改。)
答案 0 :(得分:5)
MySQL& MariaDB具有LAST_INSERT_ID()
函数,它返回当前会话中最新INSERT语句生成的id。
但是当INSERT语句插入多行时,LAST_INSERT_ID()
会在生成的集合中返回第一个 id。
在这样一批多行中,您可以依赖后续的id连续。例如,MySQL JDBC驱动程序依赖于此。
如果您插入的行包含id列的NULL和非NULL值的混合,则存在弄乱此假设的风险。 JDBC驱动程序为生成的id集合返回错误的值。
答案 1 :(得分:2)
如评论中所述,您可以捕获插入的ID(SQL Server):
use tempdb
create table test (
id int identity(1,1) primary key,
t varchar(10) null
)
create table ids (
i int not null
)
insert test(t)
output inserted.id into ids
values (null), (null), (null)
select *
from test
select *
from ids