如何使用OUTPUT-sqlserver获取标识列的值
我有一张桌子和一个扳机如何使用OUTPUT-sqlserver获取标识列的值,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,我有一张桌子和一个扳机 create table test(id int not null identity(1,1) primary key, data int); create trigger insteadTestInsert ON test INSTEAD OF INSERT AS BEGIN INSERT INTO test(data) select data FROM inserted; END; 启用触发器后,将执行以下查询 declare @tmp_table table
create table test(id int not null identity(1,1) primary key, data int);
create trigger insteadTestInsert ON test INSTEAD OF INSERT
AS
BEGIN
INSERT INTO test(data) select data FROM inserted;
END;
启用触发器后,将执行以下查询
declare @tmp_table table(id int, int_val int);
insert into test(data)
output inserted.* into @tmp_table
values (10);
select * from @tmp_table;
返回id=0,int_val=10。如果禁用(或删除)触发器,查询将返回正确的
id
如何使输出
将正确的结果插入表变量?来自
从输出返回的列反映
插入后的数据,
UPDATE或DELETE语句已被删除
已完成但在触发之前
执行
所以问题是,在执行触发器之前,inserted没有设置id
即使像这样删除触发器的内容
create trigger insteadTestInsert on test instead of insert
as
begin
return;
end
您将看到,inserted
仍然被填充,尽管表中没有插入任何内容。基本上,output
语句中的inserted
与触发器内部的inserted
匹配。From
从输出返回的列反映
插入后的数据,
UPDATE或DELETE语句已被删除
已完成但在触发之前
执行
所以问题是,在执行触发器之前,inserted没有设置id
即使像这样删除触发器的内容
create trigger insteadTestInsert on test instead of insert
as
begin
return;
end
您将看到,
inserted
仍然被填充,尽管表中没有插入任何内容。基本上,output
语句中的inserted
与触发器内部的inserted
匹配。这是一个黑客攻击,但它可以工作:
declare @tmp_table table(id int, int_val int);
insert into test(data)
output @@IDENTITY + 1, inserted.data into @tmp_table
values (10);
select * from @tmp_table;
有关使用@@IDENTITY的详细信息,请参阅。这是一种黑客攻击,但它可以工作:
declare @tmp_table table(id int, int_val int);
insert into test(data)
output @@IDENTITY + 1, inserted.data into @tmp_table
values (10);
select * from @tmp_table;
有关使用@@IDENTITY的详细信息,请参阅。这一项实际上有效
declare @tmp_table table(seq int identity, id int, int_val int);
insert into test(data)
output inserted.data into @tmp_table(int_val)
values (11),(12),(13);
update @tmp_table set id = seq + @@identity - @@rowcount
select * from @tmp_table;
select top 2 * from test order by id desc;
限制是表
test
上不能有任何其他会“损坏”@@identity变量的触发器。这一个实际上有效
declare @tmp_table table(seq int identity, id int, int_val int);
insert into test(data)
output inserted.data into @tmp_table(int_val)
values (11),(12),(13);
update @tmp_table set id = seq + @@identity - @@rowcount
select * from @tmp_table;
select top 2 * from test order by id desc;
限制是表
test
上不能有任何其他会“损坏”@@identity变量的触发器。是的,我读过,但可能不够仔细。我希望无论是否插入记录,都会填充标识列;这对于检查实际插入了哪些行很有用。谢谢你的解释。是的,我读过了,但可能不够仔细。我希望无论是否插入记录,都会填充标识列;这对于检查实际插入了哪些行很有用。谢谢你的解释。嗯@@身份-非常糟糕。:)。如果插入多行,也会很有趣,对吗?谢谢,这是一个很好的选择,但不幸的是,只有插入一行才有效。你们是对的。仅当插入一行时,它才起作用。我不确定用例是什么,所以我还是发了帖子。嗯@@身份-非常糟糕。:)。如果插入多行,也会很有趣,对吗?谢谢,这是一个很好的选择,但不幸的是,只有插入一行才有效。你们是对的。仅当插入一行时,它才起作用。我不确定用例是什么,所以我还是发布了。@a1ex07-不能保证插入临时表的数据与从inserted
@Alex Aza返回的数据的顺序相同:唯一真正重要的字段是id
。我只想在触发器主体中获得通过验证的记录(通过加入@tmp_table
和test
)@a1ex07-不能保证插入临时表的数据与从inserted
@Alex Aza返回的数据的顺序相同:唯一真正重要的字段是id
。我只想在触发器主体中获得通过验证的记录(通过加入@tmp_table
和test
)