繁体   English   中英

当一般是 raiserror 时如何提交嵌套存储过程

[英]How to commit nested stored procedure, when general is raiserror

我有一个存储过程proc_in将数据插入tbl

create table tbl(id int identity, val nvarchar(50))

create procedure proc_in
as
begin
    insert into tbl(val)
    values ('test')
end

我有proc_out我叫proc_in

create procedure proc_out
as
begin
    exec proc_in

    DECLARE @MessageText NVARCHAR(100);
    SET @MessageText = N'This is a raiserror %s';
    RAISERROR(@MessageText, 16, 1, N'MSG')
end

我如何编写proc_out它总是返回raiserror以在TBL表中插入。 我这样调用proc_out

begin tran 
    declare @err int = 0
    exec @err = proc_out
if @ERR = 0 
    commit tran 
else 
    rollback tran

您将调用包装在调用上下文中的单个事务中,因此:

begin tran 
    declare @err int = 0
    exec @err = proc_out
if @ERR = 0 
    commit tran 
else 
    rollback tran

将始终回滚该事务中发生的所有事情。

避免这种情况的一种方法是将事务移动到您的“proc_out”SP 中,例如

create procedure proc_out
as
begin
    set nocount, xact_abort on;

    exec proc_in;

    begin tran;

    -- All your other code

    if @Err = 1 begin
        rollback;

        declare @MessageText nvarchar(100);
        set @MessageText = N'This is a raiserror %s';
        --raiserror(@MessageText, 16, 1, N'MSG');
        -- Actually for most cases now its recommended to use throw
        throw 51000, @MessageText 1; 
    end; else begin
        commit;
    end;

    return 0;
end;

或者,我还没有尝试过,您可以尝试使用savepoint ,例如

create procedure proc_out
as
begin
    set nocount on;

    exec proc_in;

    save transaction SavePoint1;

    declare @MessageText nvarchar(100);
    set @MessageText = N'This is a raiserror %s';
    raiserror(@MessageText, 16, 1, N'MSG');

    return 0;
end;

然后将其称为:

begin tran;

declare @err int = 0;
exec @err = proc_out;

if @ERR = 0;
    commit tran;
end; else begin
    rollback tran SavePoint1;
    commit tran;
end;

不过我不喜欢这种方法,因为您的 SP 内部工作原理的知识现在已经泄露到调用上下文中。

无论如何,一些错误将回滚整个事务。

了解此处的XACT_ABORT设置很重要。

当 SET XACT_ABORT 为 OFF 时,在某些情况下,只有引发错误的 Transact-SQL 语句被回滚,事务继续处理。 根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。 OFF 是 T-SQL 语句中的默认设置,而 ON 是触发器中的默认设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM