SET XACT_ABORT ON不回滚RAISERROR的问题

lg314 2010-12-24 08:34:51
正常来说是这样的.有没有办法自动回滚自定义异常?
因为嵌套的存储过程比较多,如果每次执行一个存储过程以后判断返回值的话太shit了
...全文
162 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lg314 2011-01-31
  • 打赏
  • 举报
回复
使用自定义存储过程报异常

CREATE PROC ud_RAISERROR @errorstring nvarchar(4000) 
AS
RAISERROR(@errorstring,16,1)
INSERT INTO T.T SELECT 1


T.T这个表不存在
lg314 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 rucypli 的回复:]
以下代码示例显示如何在 TRY 块中使用 RAISERROR 使执行跳至关联的 CATCH 块中。它还显示了如何使用 RAISERROR 返回有关调用 CATCH 块的错误的信息。

复制代码
BEGIN TRY
-- RAISERROR with severity 11-19 will cause execution to
-- jump to the CATCH blo……
[/Quote]

恩,是这个意思.
用try catch实现类似set xact_abort on的对raiserror也适用的代码


BEGIN TRY

--代码
--RAISERROR

END TRY
BEGIN CATCH
WHILE @@TRANCOUNT<>0
ROLLBACK TRAN
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;

SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();

RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
END CATCH;


有点不太好的地方是这个代码块太繁复了,set xact_abort on一个语句解决的需要用这么长一个代码块来解决
rucypli 2010-12-24
  • 打赏
  • 举报
回复
以下代码示例显示如何在 TRY 块中使用 RAISERROR 使执行跳至关联的 CATCH 块中。它还显示了如何使用 RAISERROR 返回有关调用 CATCH 块的错误的信息。

复制代码
BEGIN TRY
-- RAISERROR with severity 11-19 will cause execution to
-- jump to the CATCH block
RAISERROR ('Error raised in TRY block.', -- Message text.
16, -- Severity.
1 -- State.
);
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;

SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();

-- Use RAISERROR inside the CATCH block to return
-- error information about the original error that
-- caused execution to jump to the CATCH block.
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
END CATCH;

billpu 2010-12-24
  • 打赏
  • 举报
回复
没看懂呀
楼主什么意思?raiserror怎么回滚?就抛一错误呀
还是怎么让set xact_abort on 开启后的 begin tran commit tran回滚?
在raiserror后面加一句
if @@error>0
rollback
不行吗
lg314 2010-12-24
  • 打赏
  • 举报
回复
create proc p1 as
set xact_abort on
begin tran
if xxxx
begin
raierror('xx',16,1)
rollback tran
return
end
commit tran

正常思路来写的话应该是这个过程,这个如果嵌套的话就麻烦了
我现在能想到的解决方法是有几个
1.在每个存储过程的raiserror后面return -1,然后每次执行以后判断,相当那个的做法.......
2.用TRY CATCH捕捉,相对于上一个来说不用执行每个存储过程以后执行,但还是不够优雅
3.邪道,刚才想到的,xact_abort对非自定义异常有效果,raiserror直接用一个出现数据库异常的存储
过程代替.

create proc ud_raiserror @errorstring varchar(200)
as
set xact abort on
raiserror(@errorstring,16,1)
insert into tt select 1

tt这个表不存在,所以执行这个肯定会报数据库错误.这样做可能性能不太好.对于大型操作来说可以无视掉这些,但一些繁琐的操作可能不太适合.或者说能有一个占用资源非常小的数据库异常.


不知道大家平时怎么处理这些问题 ??
ohfox 2010-12-24
  • 打赏
  • 举报
回复
同意对这种shit做法的定义^_^

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧