2

try-catch ブロックを含むストアド プロシージャがあります。catch ブロックでは、raiserror() を呼び出して、何らかのコンテキストでエラーを再スローします。

エラーが発生した場合、raiserror() が呼び出され、実行がストアド プロシージャから呼び出し元のコードにすぐに戻ることを期待していました。ただし、そうではないようです。ストアド プロシージャの実行は、return ステートメントに到達するまで継続するように見えます。その後、raiserror() が有効になります。

これは正しいですか? raiserror() は、return が呼び出されるか、ストアド プロシージャの最後に到達するまで効果がありませんか?

SQL Server 2012 を使用しています。

編集: ストアド プロシージャの詳細の要求に応じて、関連するコードのスニペットを次に示します。

DECLARE @ErrMsg VARCHAR(127) = 'Error in stored procedure ' + OBJECT_NAME(@@PROCID) + ': %s';

declare @UpdateDateRecordCount table (LastUpdated datetime, NumberRecords int);
begin try;
    insert into @UpdateDateRecordCount (LastUpdated, NumberRecords)
    exec sp_ExecuteSql 
        @UpdateCountQuery, 
        N'@LastUpdated datetime', 
        @LastUpdated = @LastUpdated;

    if @@rowcount <= 0
    begin;
        return 0;
    end; 
end try
begin catch;
    declare @InsertError varchar(128) = 'Error getting updated date record count: ' 
        + ERROR_MESSAGE();
    RAISERROR (@ErrMsg, 16, 1, @InsertError);
end catch;

-- Attempt to loop through the records in @UpdateDateRecordCount...

@UpdateCountQuery 引数は次のように設定されます。

N'select LastUpdated, count(*) from dbo.Part where LastUpdated > @LastUpdated group by LastUpdated;'
4

3 に答える 3

4

私が理解しているように、実行を停止したい場合は、ブロック内でエラーを発生させてから、TRYブロック内でエラーを再度発生CATCHさせる必要があります。これにより、エラーが呼び出し元に「発生」することが保証されます。

または、ブロック内のステートメントのRETURN後にステートメントを追加することもできます。これにより、プロシージャが終了し、呼び出し元に戻ります。RAISERRORCATCH

また、MSDN で提案されているように、 THROW ステートメント( ) は段階的に廃止されるため、代わりにTHROWステートメントを使用するようにしてください。RAISERRORRAISERROR

于 2013-08-14T06:28:47.257 に答える
0

使用する重大度レベルによって異なります。以下のリンクには、さらに多くの情報があります。

http://technet.microsoft.com/en-us/library/ms178592.aspx

しかし、記事を引用するには:

RAISERROR によって生成されるエラーは、データベース エンジン コードによって生成されるエラーと同じように動作します。RAISERROR によって指定された値は、ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY、ERROR_STATE、および @@ERROR システム関数によって報告されます。RAISERROR が TRY ブロックで重大度 11 以上で実行されると、関連する CATCH ブロックに制御が転送されます。RAISERROR が実行されると、呼び出し元にエラーが返されます...

したがって、重大度レベルが 11 以上の場合、制御は直ちに CATCH ブロックに転送されます。

次の例は、重大度レベル 16 を示しています。

RAISERROR ('Error raised in TRY block.', -- Message text.
16, -- Severity.
1 -- State.
);
于 2013-08-14T03:33:34.870 に答える