【问题标题】:altering a trigger to use column created within the same transaction that contains the trigger alter更改触发器以使用在包含触发器更改的同一事务中创建的列
【发布时间】:2011-12-30 18:48:42
【问题描述】:

我有一个名为 Card 的表,我正在使用一个名为 Card_shadow 的影子表进行审计。每当相应地插入、更新或删除行时,影子表都会通过 Card 表上的插入、更新和删除触发器获取新行。

现在是时候向卡片表添加一列了。正如我所看到的,我需要编写一些可以在现有事务中运行的可重复 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();
    }
}

此方法传递一个打开的连接和一个现有的事务。当调用代码提交事务时,它运行良好并且不抛出异常,但是触发器不会被更改。这就是我难住的地方。我怀疑在更改触发器之前需要提交添加的列,但我不确定。有什么想法吗?

【问题讨论】:

    标签: c# sql tsql transactions triggers


    【解决方案1】:

    我自己不确定,但是当您更改表时,触发器被填充,可能被标榜为无效或其他什么。

    alter table 命令中有一个参数来禁用和启用触发器 所以也许禁用触发器改变表,改变触发器,启用触发器将是一个goer。

    考虑到你正在做的事情,虽然我只是放下触发器然后再次创建它......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-08
      • 2017-11-08
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多