我使用带有而不是插入触发器的表时遇到问题。
我创建的表包含一个标识列。我需要在此表上使用而不是插入触发器。我还需要在触发器中查看新插入的标识的值,这需要在触发器中使用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,这个问题就会消失。
关于我做错了什么的任何想法?或者我想做的事情不可行?
谢谢。
您尚未指定“客户”是什么,但如果它们是.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如何支持标识列而不是插入触发器。
这里的罪魁祸首实际上是身份栏;如果你用一个序列替换它,那么一切正常工作™
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