我有一张名为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();
}
}
此方法传递一个打开的连接和一个现有的事务。当调用代码提交事务时,它运行正常并且不会抛出异常,但触发器不会被更改。这就是我难倒的地方。我怀疑在添加触发器之前需要提交列添加,但我不确定。有什么想法吗?
答案 0 :(得分:1)
不确定自己,但是当你改变桌子时,触发器被塞满了,可能被认为是无效的东西。
alter table命令中有一个参数用于禁用和启用触发器 所以也许禁用触发器alter table,alter trigger,enable triggers将是一个好人。
鉴于你正在做什么,虽然我只是放下触发器然后再创建它......