假设我有一张桌子
my_table(id int identity(1,1) not null primary key, data varchar(100))
我想编写一个过程,在该表中插入一个新行并返回id。 我试过了
DECLARE @new_id INT;
SELECT @new_id = id FROM
(
INSERT INTO my_table(data) OUTPUT inserted.id VALUES ('test')
) as NewVal(id)
该代码不起作用(我得到“SELECT语句中不允许嵌套的INSERT,UPDATE,DELETE或MERGE语句,该语句不是INSERT语句的直接行源。”)。但是,如果我使用表变量,我可以做
DECLARE @new_id INT;
DECLARE @tmp_table TABLE(int id);
INSERT INTO @tmp_table
SELECT id FROM
(
INSERT INTO my_table(data) OUTPUT inserted.id VALUES ('test')
) as NewVal(id);
// OR
INSERT INTO my_table(data) OUTPUT inserted.id INTO @tmp_table VALUES ('test') ;
SELECT @new_id = id FROM @tmp_table;
是否可以在不使用表变量的情况下实现相同的功能?
更新
感谢您快速回复,为每个人提供+1 SCOPE_IDENTITY解决方案。
这可能是我的错,我应该清楚地问过这个问题 - 我确实使用了MERGE
(一个例子会更长,所以我发布了INSERT
而不是INSERT
所以SCOPE_IDENTITY没有'真的对我有用。
答案 0 :(得分:5)
是的,您可以在插入后返回SCOPE_IDENTITY(由于范围不同,这比@@ IDENTITY更安全)。
即
INSERT my_table (data) VALUES ('test')
SELECT SCOPE_IDENTITY()
答案 1 :(得分:5)
比插入语句中嵌套的版本短一些是使用output...into
。
declare @tmp_table table(actiontaken nvarchar(10), id int);
merge my_table
using (values ('test')) as S(data)
on 0=1
when not matched then
insert (data) values (S.data)
output $action, inserted.id into @tmp_table;
我相信你应该使用合并中的表变量。输出可能包含多行。
答案 2 :(得分:4)
SELECT SCOPE_IDENTITY()
将获取范围中最后插入的标识值。
答案 3 :(得分:3)
如果您使用
select @@identity
您将从任何地方获取输入到标识列的最后一个值。
如果您希望从刚刚运行的脚本输入到列中的值,则应使用
select SCOPE_IDENTITY()
如果您只想从任何会话中的任何语句将最后一个值插入到给定表的标识列中,则应使用
select IDENT_CURRENT('tablename')
答案 4 :(得分:1)
select @@identity
或select SCOPE_IDENTITY()
将返回您要查找的值