如何使用OUTPUT获取标识列的值 - SQL Server

时间:2011-05-20 01:23:01

标签: 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(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的正确值。

如何使OUTPUT将正确的结果插入表变量?

3 个答案:

答案 0 :(得分:2)

来自MSDN

  

从OUTPUT返回的列反映   INSERT之后的数据,   UPDATE或DELETE语句有   完成但在触发之前   执行。

所以问题是在执行触发器之前插入没有设置id。

即使像这样删除触发器的内容

create trigger insteadTestInsert on test instead of insert 
as
begin
    return;
end

您会看到inserted仍然填充,但表中没有inserted。基本上inserted语句中的output与触发器内的inserted匹配。

答案 1 :(得分:1)

这是一个黑客攻击,但它有效:

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的详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms190315.aspx

答案 2 :(得分:1)

这个确实有效。

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变量的触发器。

相关问题