4

エラーを正しく記録していないように見えるストアド プロシージャがあります。

コードはエラーになっていますが、catch ブロックが有効になっていないようです。

try ブロックはかなり長いですが、エラー セクションはシンプルで最後にあるので、正確に説明しました。

BEGIN TRY 
insert into tbl_X
select * from #temp_tbl_Y

RETURN 1
END TRY

BEGIN CATCH
    Insert Into ExtractsErrorLog
    SELECT 
    getdate() as ErrorDate 
    ,object_name(@@procid) as ProcedureName
    ,ERROR_NUMBER() as ErrorNumber
    ,ERROR_LINE() as ErrorLine
    ,ERROR_MESSAGE() as ErrorMessage
    ;
DECLARE @errormessage as varchar(max);
DECLARE @errorseverity as int;
DECLARE @errorstate as int;

set @errormessage = ERROR_MESSAGE();
set @errorseverity = ERROR_SEVERITY();
set @errorstate = ERROR_STATE();

 RAISERROR (@errormessage,
            @errorseverity,
            @errorstate
               );


END CATCH;

proc が失敗するエラーは、古くからの友人である「列名または指定された値の数がテーブル定義と一致しません」です。私はそのエラーを修正しました - それはばかげた怠惰な間違いでした - しかし、エラーログプロセスが機能していないように見える理由に困惑しています.ExtractsErrorLogテーブルに行が挿入されていません.

4

3 に答える 3

11

TSQLTRY...CATCHはそのエラーをキャッチしません。CATCHこのエラーは、「同じ実行レベル内」のブロックで処理されない「コンパイル/再コンパイル」タイプのエラーに分類されます。

MSDNから:

次のタイプのエラーは、TRY…CATCH 構文と同じ実行レベルで発生した場合、CATCH ブロックによって処理されません。

  • 構文エラーなど、バッチの実行を妨げるコンパイル エラー。

  • 名前解決の遅延が原因でコンパイル後に発生するオブジェクト名解決エラーなど、ステートメント レベルの再コンパイル中に発生するエラー

...

TRY…CATCH を使用して、TRY ブロック内の別のバッチでエラー生成コードを実行することにより、コンパイルまたはステートメント レベルの再コンパイル中に発生したエラーを処理できます。たとえば、コードをストアド プロシージャに配置するか、sp_executesql を使用して動的な Transact-SQL ステートメントを実行することにより、これを行います。これにより、TRY…CATCH は、エラー発生よりも高い実行レベルでエラーをキャッチできます。たとえば、次のコードは、オブジェクト名解決エラーを生成するストアド プロシージャを示しています。TRY…CATCH コンストラクトを含むバッチは、ストアド プロシージャよりも高いレベルで実行されています。下位レベルで発生するエラーがキャッチされます。

トランザクションが失敗した場合にトランザクションTRY...CATCHを 作成するスクリプトで、同様の問題に遭遇しました。ROLLBACKトランザクション内のステートメントが同じエラーをスローし、トランザクションが閉じられませんCATCHでした。

MSDN の記事に記載されているように、別の方法として、INSERTステートメントからストアド プロシージャを作成し、try/catch 内でそれを呼び出す方法があります。sproc が間違っていると、作成中にコンパイル エラーが発生します。後でテーブル定義が変更されて sproc が無効になった場合、TRY...CATCHは例外をキャッチします。

すべてを 1 つのスクリプトで実行する場合は、一時ストアド プロシージャにすることができますが、sproc の作成中にコンパイル エラーを処理する必要があります。きれいではありませんが、うまくいきます:

-- Creating error sproc to re-use code
CREATE PROCEDURE #HandleError AS
    Insert Into ExtractsErrorLog
    SELECT  GETDATE() as ErrorDate 
            ,object_name(@@procid) as ProcedureName
            ,ERROR_NUMBER() as ErrorNumber
            ,ERROR_LINE() as ErrorLine
            ,ERROR_MESSAGE() as ErrorMessage;

    DECLARE @errormessage as varchar(max);
    DECLARE @errorseverity as int;
    DECLARE @errorstate as int;

    set @errormessage = ERROR_MESSAGE();
    set @errorseverity = ERROR_SEVERITY();
    set @errorstate = ERROR_STATE();

    RAISERROR ( @errormessage,
                @errorseverity,
                @errorstate);
GO

-- Create a stored procedure of our INSERT and catch any compilation errors
CREATE PROCEDURE #TEST AS
    insert into tbl_X
    select * from #temp_tbl_Y
GO
IF (@@ERROR <> 0) BEGIN
    exec #HandleError
    -- If there was an error creating the sprocs, don't continue to the next batch
    RETURN
END

-- If compilation succeeded, then run the sproc
BEGIN TRY 
    exec #TEST
    RETURN
END TRY
BEGIN CATCH
    exec #HandleError
END CATCH;
于 2014-10-16T16:20:20.643 に答える
-1

それはあなたの RETURN です。

于 2013-02-26T17:50:30.827 に答える