使用插入和刪除表的一個警告是它們都可以是空的。還有其他的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
該解決方案不是通用的,因爲需要爲每個表拼寫主鍵。
如果你運行一個MERGE語句並且一些記錄被更新了,而另一些被插入了,我會認爲你將在同一個插入表中(我沒有測試過這個,但它只是合乎邏輯)。在刪除的表中。所以我認爲你不能保證操作中的所有記錄只是一種操作類型。你是否關心它是什麼類型的操作?也許更多關於你想要完成的事情會幫助我們幫助你。 – HLGEM
我想創建一個可靠的審計線索。在其他SOF成員的幫助下,我創建了一個查詢來查找更新的ID。如果不能保證上述邏輯有效,我需要創建查詢來查找新插入和刪除的記錄。 –
@CandyChiu - 對於這種情況,我通常只是在PK上進行完整的外部連接,並檢查'INSERTED.PK是否爲空',那麼它就是一個刪除。如果'DELETED.PK是NULL',那麼它是一個插入,否則它是一個更新。如果PK本身是可更新的,那麼這將顯示爲插入/刪除,但在SQL Server中沒有辦法使用觸發器。 –