今日はSQLでのTRY~CATCHを書きますです。
SQL Server 2005からTRY~CATCHが使えるようになりました♪
Transact-SQL での TRY...CATCH の使用SQL Server 2000までは、@@ERRORのハンドリングをしていました。
@@ERRORの使用では、どのようにソースが違うのか見てみましょう♪
まずはSQL Server 2000までのエラーハンドリングです。
でも、使用テーブル等はSQL Server 2005バージョンで書いています。
BEGIN
DECLARE @ret as int ;
SELECT 1/0;
SET @ret = @@ERROR
IF @ret <> 0
goto ON_ERROR;
ON_ERROR:
IF @ret <> 0
select
message_id,
[text]
from sys.messages
where message_id = @ret and
language_id
= ( select msglangid from sys.syslanguages where [name] = N'日本語');
END
@@ERRORのハンドリングでは、処理をおこなうSQL毎に
SET @ret = @@ERROR
IF @ret <> 0
goto ON_ERROR;
の文を記載して、エラーをチェックしエラー処理ロジックへ飛ばしていました。
さてこれが、SQL Server 2005になると・・・・
BEGIN
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH
END
これだけになります。
エラー処理が違うのは、@@ERRORはエラーコードしか持っていないので、
エラーメッセージを表示させるために、エラーメッセージを格納しているテーブルからデータを取得するためです。
また、TRY~CATCHの対応で、CATCHブロックで使用される関数が提供されているからです。
Transact-SQL のエラー情報の取得を見るとエラー番号、メッセージから発生行数までわかります。
ついでにTRY~CATCHバージョンと、@@ERRORバージョンの実行計画を添付します。
これでTRY~CATCHに移行しない手はないかと思います~♪
#だめ?(w
StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- ----------------------------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
BEGIN
DECLARE @ret as int ;
SELECT 1/0; 1 1 0 NULL NULL 1 NULL NULL NULL NULL NULL NULL NULL NULL SELECT WITHOUT QUERY 0 NULL
SET @ret = @@ERROR 2 2 0 NULL NULL 2 NULL NULL NULL NULL NULL NULL NULL NULL ASSIGN 0 NULL
IF @ret <> 0 3 3 0 NULL NULL 3 NULL NULL NULL NULL NULL NULL NULL NULL COND 0 NULL
goto ON_ERROR; 4 4 3 NULL NULL 4 NULL NULL NULL NULL NULL NULL NULL NULL GOTO 0 NULL
ON_ERROR:
IF @ret <> 0 5 5 0 NULL NULL 7 NULL NULL NULL NULL NULL NULL NULL NULL COND 0 NULL
select
message_id,
[text]
from sys.messages
where message_id = @ret and
language_id
= ( select msglangid from sys.syslanguages where [name] = N'日本語'); 6 6 5 NULL NULL 8 NULL 153.1275 NULL NULL NULL 0.003315683 NULL NULL SELECT 0 NULL
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1016])) 6 7 6 Nested Loops Inner Join OUTER REFERENCES:([Expr1016]) NULL 153.1275 0 8.36E-06 2063 0.003315683 [Union1005], [Union1009] NULL PLAN_ROW 0 1
|--Assert(WHERE:(CASE WHEN [Expr1015]>(1) THEN (0) ELSE NULL END)) 6 8 7 Assert Assert WHERE:(CASE WHEN [Expr1015]>(1) THEN (0) ELSE NULL END) NULL 1 0 1.8E-07 9 2.286654E-05 [Expr1016] NULL PLAN_ROW 0 1
| |--Stream Aggregate(DEFINE:([Expr1015]=Count(*), [Expr1016]=ANY(SYSLANG.[msglangid]))) 6 9 8 Stream Aggregate Aggregate NULL [Expr1015]=Count(*), [Expr1016]=ANY(SYSLANG.[msglangid]) 1 0 8.761078E-06 17 2.268654E-05 [Expr1015], [Expr1016] NULL PLAN_ROW 0 1
| |--Table-valued function 6 10 9 Table-valued function Table-valued function NULL NULL 13.76846 0 1.392546E-05 9 1.392546E-05 SYSLANG.[msglangid] NULL PLAN_ROW 0 1
|--Concatenation 6 21 7 Concatenation Concatenation NULL [Union1005] = ([master].[sys].[sysusermsgs].[id], SYSERRORS.[message_id]), [Union1009] = ([master].[sys].[sysusermsgs].[text], SYSERRORS.[text]) 2 0 2E-07 2063 0.003284457 [Union1005], [Union1009] NULL PLAN_ROW 0 1
|--Clustered Index Seek(OBJECT:([master].[sys].[sysusermsgs].[clst]), SEEK:([master].[sys].[sysusermsgs].[id]=[@ret] AND [master].[sys].[sysusermsgs].[msglangid]=[Expr1016]) ORDERED FORWARD) 6 22 21 Clustered Index Seek Clustered Index Seek OBJECT:([master].[sys].[sysusermsgs].[clst]), SEEK:([master].[sys].[sysusermsgs].[id]=[@ret] AND [master].[sys].[sysusermsgs].[msglangid]=[Expr1016]) ORDERED FORWARD [master].[sys].[sysusermsgs].[id], [master].[sys].[sysusermsgs].[text] 1 0.003125 0.0001581 1039 0.0032831 [master].[sys].[sysusermsgs].[id], [master].[sys].[sysusermsgs].[text] NULL PLAN_ROW 0 1
|--Table-valued function 6 23 21 Table-valued function Table-valued function NULL NULL 1 0 1.157E-06 2063 1.157E-06 SYSERRORS.[message_id], SYSERRORS.[text] NULL PLAN_ROW 0 1
END 0 24 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL TEXT 0 NULL
StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
----------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------- ------------- ------------- ------------- ------------- ----------- ---------------- ---------- -------- ---------------------------------------------------------------- -------- ------------------
BEGIN
BEGIN TRY 1 1 0 NULL NULL 1 NULL NULL NULL NULL NULL NULL NULL NULL BEGIN TRY 0 NULL
SELECT 1/0; 2 2 0 NULL NULL 2 NULL NULL NULL NULL NULL NULL NULL NULL SELECT WITHOUT QUERY 0 NULL
END TRY 3 3 0 NULL NULL 3 NULL NULL NULL NULL NULL NULL NULL NULL END TRY 0 NULL
BEGIN CATCH 4 4 0 NULL NULL 4 NULL NULL NULL NULL NULL NULL NULL NULL BEGIN CATCH 0 NULL
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage; 5 5 0 NULL NULL 5 NULL NULL NULL NULL NULL NULL NULL NULL SELECT WITHOUT QUERY 0 NULL
END C 6 6 0 NULL NULL 6 NULL NULL NULL NULL NULL NULL NULL NULL END CATCH 0 NULL
ATCH
END 0 7 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL TEXT 0 NULL