使用插入和删除表的一个警告是它们都可以是空的。还有其他我应该注意的catchya吗?例如,插入的表是否可以包含新记录和更新记录?
我依靠这个逻辑来检测触发器中的动作:
IF EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted) SET @operation = 'U'
IF EXISTS(SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted) SET @operation = 'I'
IF NOT EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted) SET @operation = 'D'
IF NOT EXISTS(SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted) SET @operation = 'X'
编辑:
这是我对审计跟踪问题的解决方案。它已经在一个插入、虚假更新、真实更新和删除的 MERGE 语句上进行了测试。
ALTER TRIGGER [dbo].[LogInsertEditDelete]
ON [dbo].[<TableToAudit>]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--You will need to change @table to match the table to be audited
DECLARE @table VARCHAR(50)
SELECT @table = '<TableToAudit>'
-- date and user
DECLARE @updatedBy VARCHAR(50),
@timestamp DateTime
SELECT @updatedBy = SYSTEM_USER,
@timestamp = GETDATE()
-- Action, U = update, I = insert, D = delete
DECLARE @insertedCount int,
@deletedCount int
SET @insertedCount = (SELECT COUNT(*) FROM inserted)
SET @deletedCount = (SELECT COUNT(*) FROM deleted)
-- handle no action
IF @insertedCount = 0 AND @deletedCount = 0 RETURN
-- handle update
IF @insertedCount <> 0 AND @deletedCount <> 0
BEGIN
INSERT Audit (Type, TableName, UpdateDate, UpdatedBy, PK1)
SELECT
'U',
@table,
@timestamp,
@updatedBy,
CONVERT(VARCHAR(255), i.Id)
FROM
(SELECT Id, BINARY_CHECKSUM(*) Version FROM inserted) i
INNER JOIN
(SELECT Id, BINARY_CHECKSUM(*) Version FROM deleted) d
ON i.Id = d.Id
WHERE
i.Version <> d.Version
RETURN
END
-- handle deletes and inserts
INSERT Audit (Type, TableName, UpdateDate, UpdatedBy, PK1)
SELECT
CASE
WHEN i.Id IS NOT NULL AND d.Id IS NULL THEN 'I'
WHEN i.Id IS NULL AND d.Id IS NOT NULL THEN 'D'
END,
@table,
@timestamp,
@updatedBy,
CONVERT(VARCHAR(255), COALESCE(i.Id, d.Id))
FROM inserted i
FULL OUTER JOIN
deleted d
ON i.Id = d.Id
WHERE i.Id IS NULL OR
d.Id IS NULL
END
此解决方案不是通用的,因为需要为每个表拼出主键。