您可以使用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;