SQLのセクションで、期待どおりに動作しないことがあります(問題のパターンを示す問題のSQLの蒸留バージョンについては、以下を参照してください)。
(これはSQL Server 2008 R2 SP2 64ビット上にあります)
'do some work here'の部分でエラーが発生し、CATCHブロックでエラー処理がトリガーされます。エラー番号は515(null不可の列にnullを挿入しようとする)であるため、RAISERRORはエラーを報告しますが、ループは続行し、作業を再試行し、無限ループでエラーなどをスローします。
RAISERRORによって実行がループを終了することを期待します。ここで何が起こっているのですか?
ありがとう
WHILE (@Applied <> 1)
BEGIN
BEGIN TRY
-- === Do some work here ===
-- Successfully applied
SET @Applied = 1;
END TRY
BEGIN CATCH
-- Save the error details
SELECT
@ErrorNumber = ERROR_NUMBER(),
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
-- Test for a deadlock or uncommittable transaction
IF (@ErrorNumber = 1205 OR @ErrorNumber = 3930)
-- Sleep for 5 seconds
WAITFOR DELAY '00:00:05';
ELSE
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END
RAISERROR
は通常、実行を停止しません。 [〜#〜] throw [〜#〜] はそうですが、SQL 2012で導入されました。
RETURN;
またはRETURN -1;
の後のRAISERROR
。
以下は、MSDNページの [〜#〜] raiserror [〜#〜] の「備考」セクションからの抜粋です。
TRYブロックで重大度が11以上のRAISERRORが実行されると、関連するCATCHブロックに制御が移ります。 RAISERRORを実行すると、エラーが呼び出し元に返されます。
- TRYブロックの範囲外。
- TRYブロックの重大度が10以下。
- データベース接続を終了する重大度20以上。
以下は、動作の簡単なテストです。 2012より前のバージョンのSQL Serverで実行している場合は、コメントアウトするか、THROW
の行を削除してください。
RAISERROR(N'This is from RAISERROR - Severity 16', 16, 1);
PRINT N'----- 1';
;THROW 50505, N'This is from THROW', 1;
PRINT N'----- 2';
GO
PRINT N'----- 3';
-- WITH LOG needed for severity > 18
RAISERROR(N'This is from RAISERROR - Severity 20', 20, 1) WITH LOG;
PRINT N'----- 4';
GO
PRINT N'----- 5';
上記のテストでは、[メッセージ]タブで次のものが返されます。
メッセージ50000、レベル16、状態1、行2
これはRAISERROR-重大度16からです
----- 1
メッセージ50505、レベル16、状態1、行5
これはTHROWからのものです
----- 3
メッセージ2745、レベル16、状態2、行4
プロセスID 54でユーザーエラー50000、重大度20が発生しました。SQLServerがこのプロセスを終了しています。
メッセージ50000、レベル20、状態1、行4
これはRAISERRORの重大度20です
メッセージ0、レベル20、状態0、行0
現在のコマンドで重大なエラーが発生しました。結果がある場合は、破棄する必要があります。
また、SSMSの左下隅には「切断」と表示されます。