我一直在爲這幾天摔跤。我有一個表格觸發器,爲每個插入,更新或刪除操作創建一個審計記錄,並將其放置在相鄰數據庫的相應審計表中。這個新的審計記錄包含源表主鍵值,操作類型,記錄的XML快照,當前日期和當前用戶。多行插入時SQL觸發器觸發不正確
上面列出的每條信息都是從INSERTED \ DELETED表中分配\計算出來的,並分配給參數值,然後傳遞給存儲過程,執行一段動態SQL以插入新記錄。對於這個問題的緣故,動態SQL是一個簡單的INSERT語句(如下圖所示):
INSERT INTO [340bAudit].[aud].[TableName]
(
RecordID
,ActionType
,xml_snapshot
,ModifiedDate
,ModifiedBy
)
VALUES (@RecordPK
,@action
,@data
,GETDATE()
,SYSTEM_USER
)
這觸發出現罰款,只要工作,因爲只有被更新的記錄,但一旦發生情況多個記錄正在更新在一個單一的聲明,我得到這個:
子查詢返回超過1個值。當子查詢 跟隨=,!=,<,< =,>,> =或當子查詢用作 表達式時,這是不允許的。該語句已終止。
觸發看起來是這樣的:
ALTER TRIGGER [dbo].[RollOver_onUpdate] ON [dbo].[RollOver]
AFTER INSERT, update, DELETE
FOR EACH ROW
AS
BEGIN
/******** Audit *******/
DECLARE @TableName varchar(50)
,@RecordPK varchar(10)
,@action char(1)
,@data xml
SET @TableName = 'RollOver'
SET @RecordPK = (SELECT DISTINCT RollOverID FROM INSERTED)
SET @action = 'I'; -- Set Action to Insert by default.
IF EXISTS (SELECT * FROM DELETED)
BEGIN
SET @action =
CASE
WHEN EXISTS (SELECT * FROM INSERTED)
THEN 'U' -- Set Action to Updated.
ELSE 'D' -- Set Action to Deleted.
END
END
SET @data = CASE WHEN @action <> 'D' THEN (SELECT'<rows>' + (SELECT * FROM INSERTED i FOR xml PATH) + '</rows>')
ELSE (SELECT'<rows>' + (SELECT * FROM DELETED d FOR xml PATH) + '</rows>')
END
--Execute Audit Record Creation
EXECUTE sp_CreateAuditRecord @Table = @TableName
,@RecordID = @RecordPK
,@ActionType = @action
,@XML = @data
END
我可以改變此觸發由排在這種情況下執行?如果不是,我該從哪裏出發?
我非常想保留我與dyanamic SQL的靈活性,因爲我的數據庫中的每個表都使用相同的審計邏輯,並且這是第一個也是唯一一個看來有問題的表,到這個表的'使用'。
看看最佳實踐:編碼SQL Server的多行操作觸發http://blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/MSSQLServer/best-practice-coding-sql-服務器觸發器使其基於設置和擺脫proc電話 – SQLMenace
謝謝,我會看看這個。 – drummer0512
看起來這個鏈接不再有效。任何人都有類似資源的替代鏈接。 – drummer0512