изменение триггера для использования столбца, созданного в той же транзакции, которая содержит триггер alter - PullRequest
0 голосов
/ 17 ноября 2011

У меня есть таблица с именем 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 Ответ

1 голос
/ 17 ноября 2011

Не уверен, но когда вы изменяете таблицу, триггер заполнен, вероятно, помечен как недействительный или что-то в этом роде.

В команде alter table есть параметр для отключения и включения триггеров поэтому, возможно, отключите триггер (ы), измените таблицу, измените триггер, включите триггеры.

Учитывая то, что вы делаете, хотя я бы просто сбросил триггер, а затем создал его снова ...

...