2010-06-30 122 views
2

我有一個觸發器用於審計插入,更新和刪除的行。我從觸發器獲取舊價值和新價值方面存在問題。觸發器利用一個循環來插入以任何方式被改變的任何行的所有值(插入,更新,刪除)。但是,我的代碼沒有返回值,而是將列名稱作爲值。SQL更新/刪除觸發器無法正常工作

這裏是我的代碼部分:

SELECT @COLNAME = NAME 
FROM SYSCOLUMNS 
WHERE COLID = @FIELD AND 
    ID = (SELECT ID FROM SYSOBJECTS WHERE NAME = 'FIN_HOTEL_DTL_TYPE') 
SELECT @OLDVAL = SUBSTRING(@COLNAME, 2, LEN(@COLNAME)) FROM DELETED 
SELECT @NEWVAL = SUBSTRING(@COLNAME, 2, LEN(@COLNAME)) FROM INSERTED 
SELECT @MODBY = MODIFIED_BY FROM INSERTED 
SELECT @MODDT = MODIFIED_DATETIME FROM INSERTED 

回答

3

T-SQL僅僅是一個不同的世界。

你的代碼正在做你剛纔告訴它做的事情。 @ColName不是對列對象的引用,而是一個包含已加載列名稱的字符串值的變量。我建議你看一下example。如果你願意的話,可以閱讀整個內容,但如果你急着寫下CREATE TRIGGER Audit這個短語。

另外,花時間用set based邏輯來做到這一點 - 就像例子中那樣。通過利用T-SQL和逐行編碼來釋放債券,利用DBMS的能力和性能。不完全是。編碼循環=糟糕的表現。如果需要,DBMS將在後臺實現循環(或者希望)。

祝你好運!


我在前面試圖找到這個鏈接。我相信Paul Nielsen的this posting非常接近你想要的。

+0

是的,我想到了@ColName。我正在使用這種類型的邏輯,因爲有些表格有大量的列(遺留數據庫,不幸的是我的選擇),我不想編碼每列。 – mattgcon 2010-06-30 18:46:38

+0

美麗的答案,特別是有關避免在循環中執行此操作的部分。我已經實現了類似的觸發器,除了表現更好之外,它們更短,更簡單,沒有循環。 – TimothyAWiseman 2010-07-01 00:13:06

+0

謝謝你的幫助。我拿出了循環,並簡單地單獨引用列。 – mattgcon 2010-07-01 16:57:28