【发布时间】:2009-09-01 03:57:53
【问题描述】:
我有一个主键设置为自动递增。
我正在执行多个查询,我需要检索该主键值以用作另一个表中的外键 (IsIdentity = TRUE)。
当我执行插入查询时,有什么优雅的方法可以取回主键值吗?现在我正在重新查询并获得该列中的最高值,这看起来真的很hacky。
有什么建议吗?
【问题讨论】:
标签: sql sql-server tsql
我有一个主键设置为自动递增。
我正在执行多个查询,我需要检索该主键值以用作另一个表中的外键 (IsIdentity = TRUE)。
当我执行插入查询时,有什么优雅的方法可以取回主键值吗?现在我正在重新查询并获得该列中的最高值,这看起来真的很hacky。
有什么建议吗?
【问题讨论】:
标签: sql sql-server tsql
如果您使用的是 SQL Server 2005 或更高版本,则可以使用 OUTPUT 子句。
create table T(
pk int identity primary key,
dat varchar(20)
);
go
insert into T
output inserted.pk
values ('new item');
go
drop table T;
输出可以定向到表以及客户端。例如:
create table T(
pk int identity primary key,
dat varchar(20)
);
create table U(
i int identity(1001,1) primary key,
T_pk int not null,
d datetime
);
go
insert into T
output inserted.pk, getdate()
into U(T_pk,d)
values ('new item'), ('newer item');
go
select * from T;
select * from U;
go
drop table T, U;
从 SQL Server 2008 开始,您可以使用“可组合 DML”获得更多可能性。
【讨论】:
into 子句,这使得这比 scope_identity 对于单个记录更加笨拙跨度>
insert into YourTable values (...)
使用 scope_identity() 获取新的 PK
select scope_identity()
【讨论】:
INSERT INTO YourTable (1, 2, etc.)
OUTPUT inserted.yourIDcolumn
VALUES (value1, value2, value...)
注意:这适用于 MS SQL 2005 及更高版本
【讨论】:
SCOPE_IDENTITY() 可能是您想要的。它返回由执行它的同一代码上下文插入的最后一条记录的 ID。
IDENT_CURRENT('tablename') 会受到并发问题的影响。也就是说,不能保证在 INSERT 和对 IDENT_CURRENT 的调用之间不会插入另一条记录。
我必须承认,我不确定 VillageIdiot 的爆发指的是什么令人惊讶的原因,但我自己很惊讶这个问题似乎根本不是重复的。
【讨论】:
天哪!!!
只需调用SCOPE_IDENTITY() 函数:
insert into your_talble(col1,col2) values('blah','more blah')
select scope_identity()
因为如果任何其他语句进行插入,选择最大值将返回错误。 scope_identity() 函数返回在当前上下文中创建的标识(即由您的语句)
【讨论】:
您应该使用 scope_identity()。我建议将插入语句和 scope_identity() 包装到事务中。
【讨论】: