假设我有一张桌子
my_table(id int identity(1,1) not null primary key, data varchar(100))
Run Code Online (Sandbox Code Playgroud)
我想编写一个过程,在该表中插入一个新行并返回id.我试过了
DECLARE @new_id INT;
SELECT @new_id = id FROM
(
INSERT INTO my_table(data) OUTPUT inserted.id VALUES ('test')
) as NewVal(id)
Run Code Online (Sandbox Code Playgroud)
该代码不起作用(我得到"在INSERT语句的行的直接来源的SELECT语句中不允许嵌套的INSERT,UPDATE,DELETE或MERGE语句.").但是,如果我使用表变量,我可以这样做
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;
Run Code Online (Sandbox Code Playgroud)
是否可以在不使用表变量的情况下实现相同的功能?
更新
感谢您的快速回复,为每个人提供+1 SCOPE_IDENTITY解决方案.这可能是我的错,我应该清楚地问过这个问题 - 我确实使用过MERGE(一个例子会更长,所以我发布了INSERT),不是INSERT这样,SCOPE_IDENTITY并不适合我.
是的,您可以在插入后返回SCOPE_IDENTITY(由于范围不同,这比@@ IDENTITY更安全).
即
INSERT my_table (data) VALUES ('test')
SELECT SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)
比使用insert语句中的嵌套更短的版本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;
Run Code Online (Sandbox Code Playgroud)
我相信你应该使用合并中的表变量.输出可能包含多行.
| 归档时间: |
|
| 查看次数: |
7480 次 |
| 最近记录: |