2011-11-16 58 views
0

我有一張名爲Card的表,我正在使用名爲Card_shadow的影子表進行審計。通過插入,更新和刪除卡表上的觸發器,影子表可以隨時插入,更新或刪除行。更改觸發器以使用在包含觸發器的同一事務中創建的列更改

現在是時候在卡表中添加一列。正如我所看到的,我需要編寫一些可在現有事務中運行的可重複SQL: 1.將列添加到卡表和影子表中,並且 2.更改觸發器以使用新列

我想通過這個代碼在這裏做到這一點:

private string addVoidColumn(SqlConnection db, SqlTransaction transaction) 
{ 
    string sql = @" IF EXISTS( SELECT * 
           FROM INFORMATION_SCHEMA.COLUMNS 
           WHERE TABLE_NAME = 'Card' AND COLUMN_NAME = 'c_void_d') 
        ALTER TABLE [dbo].[Card] DROP COLUMN [c_void_d] 

        IF EXISTS( SELECT * 
           FROM INFORMATION_SCHEMA.COLUMNS 
           WHERE TABLE_NAME = 'Card_shadow' AND COLUMN_NAME = 'c_void_d') 
        ALTER TABLE [dbo].[Card_shadow] DROP COLUMN [c_void_d] 

        ALTER TABLE dbo.Card 
        ADD c_void_d datetime NULL 

        ALTER TABLE dbo.Card_shadow 
        ADD c_void_d datetime NULL"; 
    executeNonQuery(sql, db, transaction); 

    sql =   @"ALTER TRIGGER [dbo].[tr_Card_Update] 
        ON [dbo].[Card] FOR UPDATE AS 
        INSERT INTO dbo.Card_shadow(c_id_n,c_void_d,AuditAction) 
        SELECT c_id_n,c_void_d,'U' 
        FROM Inserted"; 
    executeNonQuery(sql, db, transaction); 

    sql =   @"ALTER TRIGGER [dbo].[tr_Card_Insert] 
        ON [dbo].[Card] FOR INSERT AS 
        INSERT INTO dbo.Card_shadow(c_id_n,c_void_d,AuditAction) 
        SELECT c_id_n,c_void_d,'U' 
        FROM Inserted"; 
    executeNonQuery(sql, db, transaction); 

    sql =   @"ALTER TRIGGER [dbo].[tr_Card_Delete] 
        ON [dbo].[Card] FOR DELETE AS 
        INSERT INTO dbo.Card_shadow(c_id_n,c_void_d,AuditAction) 
        SELECT c_id_n,c_void_d,'U' 
        FROM Deleted"; 
    executeNonQuery(sql, db, transaction); 
} 

private static void executeNonQuery(string sql, SqlConnection db, SqlTransaction transaction) { executeNonQuery(sql, db, transaction, 300); } 
private static void executeNonQuery(string sql, SqlConnection db, SqlTransaction transaction, int timeoutInSeconds) 
{ 
    using(SqlCommand cmd = new SqlCommand(sql,db,transaction)) 
    { 
     cmd.CommandTimeout = timeoutInSeconds; 
     cmd.ExecuteNonQuery(); 
    } 
} 

這種方法傳遞一個開放的連接,和現有的交易。當調用代碼提交事務時,它運行良好並且不會引發異常,但觸發器不會被更改。這就是我難住的地方。我懷疑在添加觸發器之前添加的列需要執行,但我不確定。有什麼想法嗎?

回答

1

不確定我自己,但是當你改變表格時觸發器被塞滿,可能被認爲是無效的東西。

在alter table命令中有一個參數來禁用和啓用觸發器 所以也許禁用觸發器alter table,alter trigger,enable triggers would be a goer。

鑑於你在做什麼,雖然我只是放下觸發器,然後再次創建它...

+0

刪除它們並重新創建工作。有趣.... Ty先生! – andrew

+0

很高興知道不是你經常做的事,這就是爲什麼我們忘記它是如何工作的.... –