MSSQL:禁用一个INSERT的触发器

时间:2009-01-30 14:18:52

标签: sql sql-server insert triggers

此问题与SQL Server 2005: T-SQL to temporarily disable a trigger

非常相似

但是我不想禁用所有触发器,甚至不需要批量命令,只需要一个INSERT。

我必须处理一个商店系统,其中原作者将一些应用程序逻辑置于触发器中(糟糕的主意!)。只要您不尝试以与原始“管理前端”不同的方式插入数据,该应用程序逻辑就可以正常工作。我的工作是写一个“从登台系统导入”工具,所以我准备好了所有数据。当我尝试插入它时,触发器会用生成的产品代码覆盖现有的产品代码(不是IDENTITY数字ID!)。要生成代码,它会将插入的自动生成ID用于另一个表,这样我甚至无法使用@@ IDENTITY查找刚插入的列,并使用实际的产品代码更新插入的行。

我可以采取任何方式避免极端笨拙的代码(将一些随机字符插入到产品名称中,然后尝试找到带有随机字符的行来更新它)。

那么:有没有办法为只有一个 INSERT禁用触发器(甚至只有一个)?

7 个答案:

答案 0 :(得分:16)

您可能会觉得这很有用:

Disabling a Trigger for a Specific SQL Statement or Session

但是你可能还面临另一个问题。 如果我了解您处于正确状态,系统会默认自动插入产品代码(通过生成值)。 现在您需要插入由某个登台系统创建的产品,并且对于该产品,其产品代码是由登台系统创建的,您希望手动将其插入到实时系统中。

如果你真的必须这样做,你需要确保将来你的实时应用程序生成的代码不会与你手动插入的代码冲突 - 我认为它们必须是唯一的。

其他方法是允许系统生成新代码并在需要时覆盖任何相应的数据。

答案 1 :(得分:12)

您可以使用以下方法禁用表格上的触发器:

ALTER TABLE MyTable DISABLE TRIGGER ALL

但是这会对所有会话都有效,而不仅仅是你当前的连接..这显然是一件非常糟糕的事情: - )

最好的方法是改变触发器本身,以便它决定是否需要运行,无论是在表上使用“insert type”标志还是其他一些方法,如果你已经存储了一些类型的排序

答案 2 :(得分:5)

您可以不改变触发器的行为,而不是禁用触发器。将一个新的可为空的列添加到名为“insertedFromImport”的表中。

在触发器中更改代码,以便触发器的违规位仅在“insertedFromImport”为空的行上运行。当您插入记录时,将“insertedFromImport”设置为非null值。

答案 3 :(得分:3)

禁用触发器,插入,提交。

SET IDENTITY_INSERT Test ON
GO

BEGIN TRAN

DISABLE TRIGGER trg_Test ON Test

INSERT INTO Test (MyId, MyField) 
    VALUES (999, 'foo')

ENABLE TRIGGER trg_Test ON Test

COMMIT TRAN

SET IDENTITY_INSERT Test OFF
GO

答案 4 :(得分:1)

您是否可以检查SUSER_SNAME()并仅在管理前端的上下文中运行?

答案 5 :(得分:1)

我看到许多可能造成问题的事情。首先更改触发器以考虑多个记录导入。这可能可能会解决您的问题。不要关闭触发器,因为它关闭的对象不仅仅是你。如果您必须在执行此操作之前将数据库置于单用户用户模式,并在非工作时间执行任务。

接下来,在任何情况下都不要使用@@ identity来获取刚插入的值!请改为使用scope_identity。如果表上的触发器也插入到具有标识字段的其他表,则@@ identity将返回错误的值。如果您现在通过系统使用@@ identity(因为我们知道您的系统有触发器),您的首要任务必须是立即查找并更改代码中所有@@ identity的实例。如果不这样做,您可能会遇到严重的数据完整性问题。这是“在修复之前停止所有工作”的问题。

至于获取刚插入的信息,请考虑在插入时创建一个batchid,然后在表中添加一个名为batchid的列(可以为空,因此不会影响其他插入)。然后你可以回拨你通过batchid插入的内容。

答案 6 :(得分:0)

如果使用BULK INSERT插入,则可以仅为插入禁用触发器。

我非常确定批量插入会要求导入文件系统上的数据文件,因此您不能只使用T-SQL。

要使用BULK INSERT,您需要INSERT和ADMINISTRATOR BULK OPERATION权限。 如果禁用触发器或约束,则还需要ALTER TABLE权限。

如果您使用的是Windows身份验证,则Windows用户需要从该文件进行读取访问。如果使用混合模式身份验证,则SQl服务器服务帐户需要从文件进行读取访问。

使用BULK IMPORT导入时,默认情况下会禁用触发器。

更多信息:http://msdn.microsoft.com/en-us/library/ms188365.aspx