我有一个问题是插入更新后触发器。测试代码如下。问题是当这个表上的事务开始时,它会回滚。
经过大量的在线研究后,似乎每个人都处于积极状态,事实并非如此。无论如何,服务器方面有什么设置我错过了吗?
我还将sp_settriggerorder()添加到第一个触发器,最后命名一个有问题的触发器。
我还注意到,禁用以下触发器可以完成交易。
低于11的严重性不是一个选项,因为它会在客户端应用程序中提示一个丑陋的警告,强制用户“扩展”#34;选择。
严重级别11到16都给了我这个问题。
USE [Test]
GO
/****** Object: Trigger [dbo].[co_bln_AfterIup] Script Date: 06/29/2017 14:43:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[co_bln_AfterIup]
ON [dbo].[co_bln]
AFTER INSERT,UPDATE
AS
IF 1 = 1
RAISERROR('test error',16,1)
答案 0 :(得分:1)
简短回答
1#在触发执行开始时设置SET XACT_ABORT
2#做一些DML(插入/更新/删除)
3#设置条件以触发RAISERROR,消息和严重性低于18
4#结果将提交带有引发错误的事务
更长的答案
在SQL Server中有两种处理错误的方法,一种是使用RAISERROR而另一种是使用THROW。您更喜欢哪一个取决于进一步的解释
使用throw你不能指定严重性,你可以使用RAISERROR 使用更高(大于18)的严重性,您可以终止用户连接,这不是您可以使用throw
执行的操作还可以在显式事务(BEGIN / END)中指定RAISERROR THROW不能(必须使用TRY / CATCH块)。
这里重要的是连接这两个错误处理程序的东西是XACT_ABORT 通过指定XACT_ABORT,您正在定义事务行为
在单个事务中,某些事务可能会失败,并且其中一些不会,取决于XACT_ABORT是ON还是OFF,这些成功事务中的一些可能会执行而其他事务不会执行,这通常是你的事情如果你想保持一致的数据库,不想这样做 有关XACT_ABORT的更多信息,请阅读here
现在这与你的错误处理程序有什么关系?
如果在事务SET SET XACT_ABORT OFF的指令处指定,则RAISERROR错误处理程序将不会回滚事务,并且您之前执行的任何操作都将反映到数据库中。 您必须使用显式ROLLBACK事务或启用XACT_ABORT
来防止这种情况如果要使用TRY / CATCH块,并进行一些错误处理,可以使用其中任何一个。无论何时调用RAISERROR或THROW,您都将直接转移到CATCH块。但请记住,即使您在catch块中,如果XACT_ABORT为OFF并且您使用的是没有ROLLBACK命令的RAISERROR,那么无论如何都将完成该事务。 如果您使用THROW,它将立即回滚
然而,XACT_ABORT开启或关闭对THROW处理程序没有影响,并将按预期执行(回滚所有更改)
另请注意,即使XACT_ABORT为OFF,您仍然可以使用18以上的严重性回滚事务
因此,根据您想要达到的目标,您可以选择最适合您的方式。遵循标准,THROW是最好的,它更新但是如果你想只显示警告 - 回到简短回答
答案 1 :(得分:0)