www.pon-x.jp
前回の続き
前回から、トランザクションの実装をしてますが、今回はエラーを検知してロールバックしてみたいと思います。
エラー検知
エラー検知はこのような構文です。
BEGIN TRY
END TRY
BEGIN CATCH
END CATCH
こんな感じです。
前回の内容に組み込んでみる。
では、早速やってみましょう。
IF OBJECT_ID(N'tempdb..#TEMP', N'U') IS NOT NULL
DROP TABLE #TEMP
CREATE TABLE #TEMP
(
NUM BIGINT,
TXT NVARCHAR(10)
)
BEGIN TRY
BEGIN TRANSACTION
DECLARE @CNT INT
SET @CNT = 0
WHILE @CNT <= 30
BEGIN
INSERT INTO #TEMP
VALUES(
POWER(2, @CNT),
'2^' + CONVERT(VARCHAR, @CNT)
)
IF @CNT = 20
SET @CNT = @CNT / 0
SET @CNT += 1
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
SELECT * FROM #TEMP
上記の内容は、WHILEのループ内で@CNTが20の時に、わざとエラーを発生させています。
エラーをキャッチしてロールバックしているので、#TEMPはからになって、最後に出力されます。
こんな感じです。

ロールバックしないで、エラーが出るまで処理をする
通常、エラーがでたら処理がとまってしまうのですが、TRY~CATCHはうまくエラーをハンドリングすることができます。
では、エラーがでるまで処理するというよみましょう。
IF OBJECT_ID(N'tempdb..#TEMP', N'U') IS NOT NULL
DROP TABLE #TEMP
CREATE TABLE #TEMP
(
NUM BIGINT,
TXT NVARCHAR(10)
)
BEGIN TRY
BEGIN TRANSACTION
DECLARE @CNT INT
SET @CNT = 0
WHILE @CNT <= 30
BEGIN
INSERT INTO #TEMP
VALUES(
POWER(2, @CNT),
'2^' + CONVERT(VARCHAR, @CNT)
)
IF @CNT = 20
SET @CNT = @CNT / 0
SET @CNT += 1
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT('##### ERROR #####')
PRINT('@CNT -> ' + CONVERT(VARCHAR, @CNT))
PRINT('##### ERROR #####')
RETURN
END CATCH
SELECT * FROM #TEMP
上記の内容は、WHILEのループ内で@CNTが20の時に、わざとエラーを発生させています。
@CNTを0で割ろうとしていますが、分母が0になる数は存在しないので、エラーになります。
こんなかんじの出力です。
@CNTが20でおわっているのが確認できますね。
BEGIN CATCH以下の内容を確認しておこう。
BEGIN CATCH
PRINT('##### ERROR #####')
PRINT('@CNT -> ' + CONVERT(VARCHAR, @CNT))
PRINT('##### ERROR #####')
RETURN
END CATCH
SELECT * FROM #TEMP
こんなかんじですが、RETURNで処理を終了しています。
つまり、それ以下のSELECT * FROM #TEMPは処理されないということになります。
SELECT * FROM #TEMPは、もしエラーが発生されなかったら処理されるといことになります。
こんなかんじで、エラーがあったときにそこで終わるのかどうかということも明示しておく必要があります。
以上、今回はここまで。S