也许是一个愚蠢的问题!
如果我从After Insert触发器(T-SQL)调用存储过程 - 那么如何获取“刚插入”数据的值? e.g。
CREATE TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
EXEC createAuditSproc 'I NEED VALUES HERE!'
我没有任何标识列需要担心 - 我只想使用一些“刚插入”的值传递给我的sproc。
编辑:为了澄清 - 我需要这个来调用一个sproc而不是直接插入到表中,因为sproc不止一件事。我正在处理一些我目前无法正确修改的遗留表(时间/资源/遗留代码),所以我必须使用我所拥有的:(
答案 0 :(得分:23)
您可以使用INSERTED and DELETED伪表来获取新的“已更改”数据:
CREATE TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
INSERT INTO myTableAudit(ID, Name)
SELECT i.ID, i.Name
FROM inserted i;
END
给出示例表
create table myTable
(
ID INT identity(1,1),
Name varchar(10)
)
GO
create table myTableAudit
(
ID INT,
Name varchar(10),
TimeChanged datetime default CURRENT_TIMESTAMP
)
GO
编辑:道歉,我没有解决有关调用存储过程的问题。根据marc_s的注释,请注意插入/删除的行可能包含多行,这使得SPROC的问题变得复杂。就个人而言,我会将触发器直接插入审计表而不需要封装SPROC。但是,如果您有SQL 2008,则可以使用表值参数,如下所示:
CREATE TYPE MyTableType AS TABLE
(
ID INT,
Name varchar(10)
);
GO
CREATE PROC dbo.MyAuditProc @MyTableTypeTVP MyTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO myTableAudit(ID, Name)
SELECT mtt.ID, mtt.Name
FROM @MyTableTypeTVP mtt;
END
GO
然后你的触发器会被改变,如下所示:
ALTER TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @MyTableTypeTVP AS MyTableType;
INSERT INTO @MyTableTypeTVP(ID, Name)
SELECT i.ID, i.Name
FROM inserted i;
EXEC dbo.MyAuditProc @MyTableTypeTVP;
END
然后,您可以测试这适用于单个和多个插入
insert into dbo.MyTable values ('single');
insert into dbo.MyTable
select 'double'
union
select 'insert';
但是,如果您使用的是SQL 2005或更低版本,则可能需要使用游标将插入的传递行循环到您的SPROC,这太难以考虑了。
作为旁注,如果您有SQL 2008,可以查看Change Data Capture
编辑#2 :因为您需要调用proc,并且如果您确定只插入一行...
ALTER TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SomeInt INT;
DECLARE @SomeName VARCHAR(10);
SELECT TOP 1 @SomeInt = i.ID, @SomeName = i.Name
FROM INSERTED i;
EXEC dbo.MyAuditProc @SomeInt, @SomeName;
END;