2011-09-06 57 views
0

我在數據庫中有一個大表,我想跟蹤對各個記錄所做的更改。更確切地說,我想記錄日期和對列進行的更改。使用觸發器保存SQL Server 2008中的更新列

由於表格中有25個以上的列,我不想單獨測試它們。

日誌記錄表看起來像ID-Date-Table-Column-OldValue-NewValue

在我AFTER UPDATE觸發我想檢查哪些列有不同的值,並將其登錄到我的表。

我知道我可以得到表的列有:

DECLARE @meta_table TABLE ( 
    idx smallint Primary Key IDENTITY(1,1) 
    , TABLE_NAME nchar(100), COLUMN_NAME nchar(100), COLUMN_ID int 
) 

INSERT @meta_table 
SELECT TABLE_NAME, COLUMN_NAME, 
    COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 
    COLUMN_NAME, 'ColumnID') AS COLUMN_ID 
FROM MYDATABASE.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'myTable'; 

我可以遍歷列:

SET @i = 1 
SET @numrows = (SELECT COUNT(*) FROM @meta_table) 
IF @numrows > 0 
    WHILE (@i <= (SELECT MAX(idx) FROM @meta_table)) 
    BEGIN 
     SET @col = (SELECT COLUMN_NAME FROM @meta_table WHERE idx = @i) 

     -- do something with @col 

     SET @i = @i + 1 
    END 

在第一個步驟,我想檢查所有列,但像這樣的東西不起作用

IF (SELECT @col FROM inserted) <> (SELECT @col FROM deleted) 
BEGIN 
    -- INSERT into logging table ... 
END 

此外,這隻會檢查第一行的更新,所以我woul d需要爲刪除/插入表中的每一行執行此操作。

+0

你看過COLUMNS_UPDATED()嗎? – HABO

回答

0

嗯 - 如果您只想記錄已更改的字段,那麼您肯定需要分別檢查每個字段。但是,正如您發現的那樣,比較在不同的數據類型上工作不一樣。所以你可能需要檢查每個字段的數據類型,並做相應的比較。我相信這是一個名爲INFORMATION_SCHEMA「DATA_TYPE」字段,所以當你做你的元表插入,添加其他列:

 

INSERT @meta_table 
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, 
    COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 
    COLUMN_NAME, 'ColumnID') AS COLUMN_ID 
FROM MYDATABASE.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'myTable'; 

 

,然後在循環檢查它:

 

SET @i = 1  
SET @numrows = (SELECT COUNT(*) FROM @meta_table)  
IF @numrows > 0  
    WHILE (@i <= (SELECT MAX(idx) FROM @meta_table))  
    BEGIN  
     SELECT @col = COLUMN_NAME, @dataType = DATA_TYPE 
     FROM @meta_table WHERE idx = @i) 

     -- do something with @col 

     SET @i = @i + 1  
    END 
 

然後你有頂級檢查數據類型,你做比較之前..

 

IF(@dataType = 'varchar') 
BEGIN 

-- do your comparison and insert here 

END 
ELSE IF(@dataType = 'int') 
BEGIN 

-- do you comparison and insert here 

END 
.... 


 

...等等,所有不同的數據類型,你在表中有...

+0

嗯 - 所以我想你也想這樣做多行,在一個更新語句修改多行的情況下 - 在這種情況下,你需要光標選擇所有修改後的行,然後檢查每一行.... –

2

迭代表格列沒有意義。由於觸發器是針對特定的表格,因此您已經知道它具有哪些列!用你感興趣的列簡單地編寫觸發器。你說這可能是一個重複的,無聊的,容易出錯的任務?好的程序員在這種情況下自動執行任務,例如。通過代碼生成自動生成觸發器,瞬間重構它們並使其與模式更改保持同步。部署運行時模式發現不是要走的路。

+0

這些列不在我的控制之下,可以隨時添加/刪除,所以我必須在運行時獲取列。 – Darcara