如何在一个INSERT上插入多行的ID?

时间:2018-04-30 14:40:38

标签: mysql sql mariadb

我想使用单个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字段的选项,或类似的东西;给出自动增量字段,不能更改。)

2 个答案:

答案 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