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、DBエンジンは呼び出し元のストアドプロシージャからのロールバックを保証しますか?

明確になることを願っています。

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して、全体とセーブポイントをロールバックするかどうかを決定できます。

とまたはの間でデータベースに対して行うすべてのことはトランザクションの一部であり、いずれかの行でエラーが発生した場合、制御はトランザクションがロールバックされるブロックに ルーティングされます。テーブル変数のようなものはこのスコープの外にあり、ロールバックされません。そして、@ David Brabantが言ったように、ブロック にあるべきです。BEGIN TRANSACTIONCOMMITROLLBACKCATCHBEGIN TRANSACTIONBEGIN TRY

于 2012-06-21T13:37:06.680 に答える