6

我需要使用通用EXEC命令从另一个执行存储过程。我需要确定,所有的 sql 语句都将在事务中。

BEGIN TRANSACTION
BEGIN TRY   

    SET @Esercizio = (SELECT ESERCIZIO_OBIETTIVI_CONSUNTIVARE from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)
    SET @TipoProcesso = (SELECT ISNULL(TipoProcesso, 'middle') from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)

    DELETE FROM TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
    DELETE FROM TB_SCHEDE_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
    DELETE FROM TB_OBIETTIVI WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO =  @Esercizio
    DELETE FROM TB_OBIETTIVI_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO =  @Esercizio

    EXEC AnotherStore @iCOD_VALUTAZIONE, @iMATRICOLA, @TipoProcesso
    COMMIT TRANSACTION

END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
END CATCH

如果AnotherStore过程抛出异常,数据库引擎是否确保从调用者存储过程回滚?

希望清楚。

4

2 回答 2

2

有关事务存在时执行处理的示例,请参阅异常处理和嵌套事务:

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch   
end
于 2012-06-21T13:53:58.410 回答
1

简单的答案是肯定的,它会回滚调用者存储过程的更改,但是如果您在另一个存储过程中有事务,请仔细考虑,如果是这种情况,则可能会出现与您预期不同的情况。AROLLBACK将影响所有事务,尽管这可能是您想要的。您可以@@TRANCOUNT在您的捕获中使用并确定是否要回滚整个事物以及保存点。

您在and or之间对数据库所做的一切都是事务的一部分,如果任何行出错,控制将被路由到事务将回滚的块。 诸如表变量之类的东西会超出这个范围并且不会被回滚。正如@David Brabant 所说,应该在街区内。 BEGIN TRANSACTIONCOMMITROLLBACKCATCHBEGIN TRANSACTIONBEGIN TRY

于 2012-06-21T13:37:06.680 回答