当前位置: 首页 > 面试题库 >

如何忽略触发器中的错误并在MS SQL Server中执行相应的操作

易研
2023-03-14
问题内容

我创建了AFTER INSERT TRIGGER

现在,如果在执行触发器的过程中发生错误,则将出现任何情况。它不应影响对触发表的插入操作。

一言以蔽之,如果在触发器中发生任何错误,则应将其忽略。

如我所用

BEGIN TRY

END TRY
BEGIN CATCH

END CATCH

但是它给出以下错误信息并在触发表上回滚插入操作

触发器执行期间引发了错误。批处理已中止,并且用户事务(如果有)已回滚。


问题答案:

有趣的问题。默认情况下,触发器被设计为如果触发器失败,则会回滚触发它的命令。因此,无论何时执行触发器,都会有一个活动事务,无论是否存在显式的BEGIN
TRANSACTION。并且触发器内的BEGIN / TRY也将不起作用。最佳实践是不要在触发器中编写任何可能会失败的代码-除非希望也使触发语句失败。

在这种情况下,要抑制此行为,有一些解决方法。

选项A(丑陋的方式):

由于事务在触发器开始时处于活动状态,因此您可以COMMIT对其进行设置并继续执行触发器命令:

CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT
AS
BEGIN
COMMIT;
... do whatever trigger does
END;

请注意,如果触发代码中有错误,这仍会产生错误消息,但是Test1表中的数据已安全插入。

选项B(也很丑):

您可以将代码从触发器移动到存储过程。然后从实现的Wrapper SP调用该存储过程,BEGIN/TRY最后从触发器调用Wrapper
SP。INSERTED如果逻辑上需要(现在是在SP中),从表中移动数据可能有点棘手-可能使用一些临时表。

SQLFiddle演示



 类似资料:
  • 问题内容: 我有通过virtualbox在Windows上运行的boot2docker 1.4.1。我支持MITM https证书的代理。我通过在中添加以下行来配置代理: 然而,当我跑我得到 请帮助我找出忽略证书错误的正确方法。谢谢! 问题答案: 编辑 看起来新的docker仅适用于Windows 10的某些版本 。如果您仍然停留在Windows 7上,我已经更新了以下内容,以反映安装最新版本的d

  • 问题内容: 我有一个包含URL和代表其参数的字符串的表。问题是我希望url和parameterstring是表的唯一约束-aka没有条目可以具有相同的url AND parameter string。参数字符串可以是任意长度(长于800bytes左右,这是MySql键的最大长度,因此我不能使用Unique(url,params),因为它会引发错误…)。 我曾考虑过使用触发器来执行此操作,但是如果触

  • 正如问题所述,我有一个机器人,我正在使用它向所有被邀请加入的行会发送特定频道的消息。首先,在我的控制实验中,这个功能在我用3台服务器做的控制实验中起作用,我用机器人需要的通道来中继我所有的消息。然后,当我的bot公开时,一些成员的服务器中没有此通道,这导致我的bot在执行我的测试/中继功能时显示。 我希望bot能够将我的中继消息发送到我指定的频道名称,并忽略其服务器中没有该频道的所有人,并继续将消

  • 这应该很容易做到。我可以在Guzze3中找到很多关于如何做到这一点的参考资料,但是它们在Guzze5中不起作用。 我目前正在做的事情: 当我发送请求时,我收到了这个错误: 我在谷歌上找不到任何关于这个错误的有用参考。如果我可以访问旋度选项,那么我可以尝试类似这里建议的解决方案(这是针对Guzzle 3的,因此它不起作用):http://inchoo.net/dev-talk/symfony2-gu

  • 问题内容: 我必须将文本文件读入Python。文件编码为: 这是一个第三方文件,我每天都会得到一个新文件,所以我宁愿不更改它。该文件具有非ASCII字符,例如Ö。我需要使用python读取行,并且我可以忽略掉具有非ascii字符的行。 我的问题是,当我用Python读取文件时,到达非ASCII字符所在的行时出现UnicodeDecodeError,而我无法读取文件的其余部分。 有没有办法避免这种情

  • 问题内容: 如果我 在表上有,如何抛出错误以阻止对该表进行更新? 问题答案: 这是一种可行的技巧。这不是干净的,但看起来可能可行: 本质上,您只是尝试更新不存在的列。