I have a table called Card that I am auditing with a shadow table called Card_shadow. The shadow table gets a new row via insert, update and delete triggers on the Card table anytime a row is inserted, updated, or deleted accordingly.
Now comes time to add a column to the card table. As I see it, I need to write some repeatable SQL that can be run in an existing transaction that will:
1. Add the column to the card table and the shadow table, and
2. Alter the triggers to use the new column
I am trying to do this via this here code:
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();
}
}
This method is passed an open connection, and an existing transaction. When the calling code commits the transaction, it runs fine and throws no exceptions, however the triggers do not get altered. And this is where I’m stumped. I have a suspicion that the column adds need to be committed before the triggers can be altered, but i’m not sure. Any thoughts?
Not sure myself, but whe you alter the table the trigger is stuffed, probably narked as invalid or something.
There is an a parameter in alter table comand to disable and enable triggers
so maybe disable trigger(s) alter table, alter trigger, enable triggers would be a goer.
Given what you are doing though I’d just drop the trigger and then create it again…