2011-11-16 57 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

很高兴知道不是你经常做的事,这就是为什么我们忘记它是如何工作的.... –