使用OUTPUT / INTO而不是insert trigger会使'inserted'表无效

时间:2010-03-20 05:12:09

标签: sql triggers identity

我在使用带有而不是插入触发器的表时遇到问题。

我创建的表包含一个标识列。我需要在此表上使用而不是插入触发器。我还需要在触发器中查看新插入的标识的值,这需要在触发器中使用OUTPUT / INTO。问题是执行INSERT的客户端无法看到插入的值。

例如,我创建了一个简单的表:

CREATE TABLE [MyTable](
 [MyID] [int] IDENTITY(1,1) NOT NULL,
 [MyBit] [bit] NOT NULL,
 CONSTRAINT [PK_MyTable_MyID] PRIMARY KEY NONCLUSTERED 
(
 [MyID] ASC
))

接下来我创建一个简单的而不是触发器:

create trigger [trMyTableInsert] on [MyTable] instead of insert
as
BEGIN
 DECLARE @InsertedRows table( MyID int,
                              MyBit bit);

 INSERT INTO [MyTable]
      ([MyBit])
   OUTPUT inserted.MyID,
          inserted.MyBit
   INTO @InsertedRows
   SELECT inserted.MyBit
     FROM inserted;

 -- LOGIC NOT SHOWN HERE THAT USES @InsertedRows
END;

最后,我尝试执行插入并检索插入的值:

DECLARE @tbl TABLE (myID INT) 

insert into MyTable 
 (MyBit)
OUTPUT inserted.MyID
  INTO @tbl
 VALUES (1)

 SELECT * from @tbl

问题是我所得到的一切都是零。我可以看到行已正确插入表中。我也知道如果我从触发器中移除OUTPUT / INTO,这个问题就会消失。

关于我做错了什么的想法?或者我想做的事情不可行?

感谢。

2 个答案:

答案 0 :(得分:2)

您尚未指定“客户”是什么,但如果它们是.Net或类似应用,则只需删除输出的INTO部分即可。您的客户端无法查看结果,因为它们未在结果集中返回。

您的触发器应如下所示:

create trigger [trMyTableInsert] on [MyTable] instead of insert
as
BEGIN

 INSERT INTO [MyTable]
      ([MyBit])
   OUTPUT inserted.MyID,
          inserted.MyBit
   SELECT inserted.MyBit
     FROM inserted;

 -- LOGIC NOT SHOWN HERE THAT USES @InsertedRows
END;

这导致插入行为就客户端而言就像select查询一样 - 您可以迭代结果以获取标识值(或其他特殊值,如Timestamp)。

这就是LinqToSql如何支持标识列而不是插入触发器。

答案 1 :(得分:0)

罪魁祸首实际上是身份栏;如果您将其替换为序列,那么一切都将正常工作

create sequence testing_id as int start with 1 increment by 1

create table testing (id int default (next value for testing_id), s varchar(100))

create trigger tr_testing on testing instead of insert as
begin
    declare @inserted table (id int, s varchar(100))
    insert into testing
    output inserted.* into @inserted
    select * from inserted
end

declare @inserted table (id int, s varchar(100))
insert into testing (s)
output inserted.* into @inserted
values ('testing1'),('testing2')

select * from @inserted