Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用OUTPUT-sqlserver获取标识列的值_Sql_Sql Server_Tsql_Sql Server 2008 - Fatal编程技术网

如何使用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