Blu*_*ppy 16 t-sql triggers stored-procedures
也许是一个愚蠢的问题!
如果我从After Insert触发器(T-SQL)调用存储过程 - 那么如何获取"刚插入"数据的值?例如
CREATE TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
EXEC createAuditSproc 'I NEED VALUES HERE!'
Run Code Online (Sandbox Code Playgroud)
我没有任何标识列需要担心 - 我只是想使用一些"刚插入"的值传递给我的sproc.
编辑:为了澄清 - 我需要这个来调用一个sproc而不是直接插入到表中,因为sproc不止一件事.我正在使用一些我目前无法修改的遗留表来"正确地"做事(时间/资源/遗留代码),所以我必须使用我拥有的东西:(
Stu*_*tLC 25
您可以使用INSERTED和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
Run Code Online (Sandbox Code Playgroud)
给出示例表
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
Run Code Online (Sandbox Code Playgroud)
编辑:道歉,我没有解决有关调用存储过程的问题.根据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
Run Code Online (Sandbox Code Playgroud)
然后你的触发器会被改变,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
然后,您可以测试这适用于单个和多个插入
insert into dbo.MyTable values ('single');
insert into dbo.MyTable
select 'double'
union
select 'insert';
Run Code Online (Sandbox Code Playgroud)
但是,如果您使用的是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;
Run Code Online (Sandbox Code Playgroud)