如何在不触发更新触发器的情况下更新 SQL Server 表

7

我有一个更新触发器,它会更新表tblCurrent中的一些重要状态字段。
当我第一次上传每天的批量记录到tblCurrent时(大约10K条记录),我仅在这三个存储过程首次上传时执行一些UPDATE操作。如何防止更新触发器在这三个初始UPDATE期间运行?


一个不好的 hack 是创建另一个表,该表与您的其他表分组。这个新表有1列,称为 locked。它可以是 true 或 false。在存储过程之前,将其设置为 false。在存储过程之后将其设置为 true。当然,这意味着所有查询都必须手动检查条件,但这就是我们的做法。这是一种丑陋的 hack,容易出现人为错误,但它确实有效。 - Dave
3个回答

8
您可以暂时禁用表上的触发器,然后再启用它们。请参考MSDN文章
禁用语法:DISABLE TRIGGER {[schema_name.]trigger_name[, ...n] | ALL} ON {object_name | DATABASE | ALL SERVER}[;]
启用语法:ENABLE TRIGGER {[schema_name.]trigger_name[, ...n] | ALL} ON {object_name | DATABASE | ALL SERVER}[;]
例如,要禁用给定表的所有触发器,请运行以下语句:
DISABLE TRIGGER ALL ON tblCurrent;

8
但这会影响到其他并发连接,不是一个好主意。以下文章提供了一些替代方案:http://www.mssqltips.com/sqlservertip/1591/disabling-a-trigger-for-a-specific-sql-statement-or-session/ - Joe
这太完美了。我每天运行三个存储过程,用于tblCurrent的新批记录,启用触发器时总共需要长达二十分钟的时间。现在只需要不到五分钟的时间。谢谢。 - aSystemOverload

4
有一种方法可以做到这一点,即在 tblCurrent 中放置一些数据,使您能够检测到所描述的“第一次上传”的情况。例如,一个名为“FirstUploaded”的 BIT 列,或者是当首次上传时为空的列,甚至是一个名为“DontFireTrigger”的 BIT 列。

然后编写触发器来检测此条件,并有条件地更新状态字段。

不可否认,这看起来像是一个恶劣的 hack,但也许并不比其他解决方案差。


0
你可以使用会话变量Context_Info。在更新之前将context_info设置为某个值,然后在触发器内测试它。
-- 更新代码 SET Context_Info 0x55555 Update Table set ...
-- 触发器内的代码 SELECT @Cinfo = Context_Info() IF @Cinfo <> 0x55555 BEGIN ... END

会话变量将在多个函数、触发器等之间全局存在。如果有人尝试多次使用这种方法,Context_Info 将被混合。这可能会导致错误。更好的方法是创建临时表并检查其是否存在(通过系统目录)- 每次都可以为此类表使用唯一名称。 - Evgeny Nozdrev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接