SQL Server 2005から念願のTRY ... CATCHステートメントがサポートされました。
BEGIN TRY
~
END TRY
BEGIN CATCH
~
END CATCH
と書くんですが、そのままだと例外を握りつぶしちゃいますので、
http://msdn2.microsoft.com/ja-jp/library/ms178592(SQL.90).aspx
の例AのようにRAISERRORで例外を伝播させなきゃいけません。
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
やっていることは単なる移送なので、問題はないのですが曲者はERROR_STATE関数です。こいつが実は0を返す場合があるのです。0を返すと、RAISERRORにそのまま0がセットされるのですが、
値 0 は状態には無効です。有効な範囲は 1 から 127 までです。
とRAISERRORのエラーが発生します(;_;)
となると、やることはひとつ補正です
begin catch
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
IF ( @ErrorState < 1 OR 127 < @ErrorState )
BEGIN
SET @ErrorState = 1
END
rollback transaction
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
return
end catch
こんな感じになりました。
いいんだろうか・・・orz