1. ホーム
  2. データベース
  3. mssql2005

SQL Server 2005 で Try Catch を使って例外を処理する

2022-01-20 10:57:10

TRY.... .CATCHは、Sql Server 2005/2008の印象的な新機能です。これは、開発者の例外処理を改善するものです。Try... を試さない理由はないでしょう。Catch 機能を試さない理由はありません。

* TRYブロック - 例外を発生させる可能性のあるコードやスクリプトが含まれています。
* CATCHブロック - TRYブロックで例外が発生した場合、コードの処理フローはCATCHブロックにルーティングされます。ここでは、例外処理、ロギングなどを行うことができます。
Sql Server の Try Catch は、C# や JAVA などの言語と同系統のものです。この一貫性が最大のイノベーションです。

I. SQL SERVER 2000 における例外処理

CREATE PROC usp_AccountTransaction 
 
  @AccountNum INT, 
 
  @Amount DECIMAL 
 
AS 
 
BEGIN 
 
  BEGIN TRANSACTION --beginning a transaction. 
 
    UPDATE MyChecking SET Amount = Amount - @Amount 
 
      WHERE AccountNum = @AccountNum 
 
    IF @@ERROR ! = 0 --check @@ERROR variable after each DML statements... 
 
    BEGIN 
 
      ROLLBACK TRANSACTION --RollBack Transaction if Error... 
 
      RETURN 
 
    END 
 
    ELSE 
 
    BEGIN 
 
      UPDATE MySavings SET Amount = Amount + @Amount 
 
        WHERE AccountNum = @AccountNum 
 
      IF @@ERROR ! = 0 --check @@ERROR variable after each DML statements... 
 
      BEGIN 
 
        ROLLBACK TRANSACTION --RollBack Transaction if Error... 
 
        RETURN 
 
      END 
 
      ELSE 
 
      BEGIN 
 
        COMMIT TRANSACTION --finally, Commit the transaction if Success. 
 
        RETURN 
 
      END 
 
    END 
 
END 
 
GO 

上記はSql server 2000のプロシージャで、トランザクションをコミット/ロールバックするためにデータベース操作の直後に@@ERRORをチェックする必要があります。
Sql server 2000でエラーを監視する唯一の方法は、グローバルトラバーサルの@ERRORを監視することです。そのため、各操作の直後に監視する必要があります。

II. SQL SERVER 2005 における例外処理

トライ... CATCH は、SQL Server 2005 で提供される、より読みやすい構文です。開発者なら誰でもこの書き方に慣れているはずです。SQL Server 2005 では、この @@ERROR の使用法をまだサポートしています。

1. try catch 構文。

BEGIN TRY 
 
  Try Statement 1 
 
  Try Statement 2 
 
  ... 
 
  Try Statement M 
 
END TRY 
 
BEGIN CATCH 
 
  Catch Statement 1 
 
  Catch Statement 2 
 
  ... 
 
  Catch Statement N 
 
END CATCH 

2. エラーメッセージを取得するための関数の表です。

CATCHブロックでは、以下のシステム関数が有効です。より多くのエラーメッセージを取得するために使用することができます。

機能説明

ERROR_NUMBER()は、CATCHブロックが実行される原因となったエラーメッセージのエラー番号を返します。
ERROR_SEVERITY() は、CATCH ブロックが実行される原因となったエラーメッセージの深刻度レベルを返します。
ERROR_STATE() は、CATCH ブロックが実行される原因となったエラーメッセージのステータス番号を返します。
ERROR_PROCEDURE() は、エラーを発生させたプロシージャの名前を返します。
ERROR_LINE() は、エラーが発生した行番号を返します。
ERROR_MESSAGE() は、CATCH ブロックが実行される原因となったエラー・メッセージの全文を返します。

簡単な例です。

BEGIN TRY 
 
  SELECT GETDATE() 
 
  SELECT 1/0--Evergreen divide by zero example! 
 
END TRY 
 
BEGIN CATCH 
 
  SELECT 'There was an error! ' + ERROR_MESSAGE() 
 
  RETURN 
 
END CATCH; 



3. トライキャッチ・ロールバック/コミット・トランザクションの例

ALTER PROC usp_AccountTransaction 
 
  @AccountNum INT, 
 
  @Amount DECIMAL 
 
AS 
 
BEGIN 
 
  BEGIN TRY --Start the Try Block... 
 
    BEGIN TRANSACTION -- Start the transaction. 
 
      UPDATE MyChecking SET Amount = Amount - @Amount 
 
        WHERE AccountNum = @AccountNum 
 
      UPDATE MySavings SET Amount = Amount + @Amount 
 
        WHERE AccountNum = @AccountNum 
 
    COMMIT TRAN -- Transaction Success! 
 
  END TRY 
 
  BEGIN CATCH 
 
    IF @@TRANCOUNT > 0 
 
      ROLLBACK TRAN -- RollBack in case of Error 
 
    -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception 
 
    RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1) 
 
  END CATCH 
 
END 
 
GO

III. 説明例

エラーログテーブルを作成します。

CREATE TABLE ErrorLog(errNum INT,ErrSev NVARCHAR(1000),ErrState INT,ErrProc NVARCHAR(1000),ErrLine INT, ErrMsg NVARCHAR(2000))

エラーログを記録するプロシージャを作成します。

CREATE PROCEDURE ErrorLog
AS 
   SELECT ERROR_NUMBER() AS ErrNum,ERROR_SEVERITY() AS ErrSev,ERROR_STATE() AS ErrState,ERROR_PROCEDURE() AS ErrProc,ERROR_LINE() AS ErrLine, ERROR_MESSAGE() AS ErrMsg 
   INSERT 
   INTO ErrorLog 
   VALUES(ERROR_NUMBER(),ERROR_SEVERITY(),ERROR_STATE(),ERROR_PROCEDURE(),ERROR_LINE(),ERROR_MESSAGE())
GO

ストアドプロシージャを書こう その中で Try Catch を使いましょう。

USE [Your_Test]
GO
/****** Object: StoredProcedure [dbo]. [getTodayBirthday].  
    Script Date: 05/17/2010 15:38:46 
    Author:jinho
    Desc:Get all the people whose birthday is today
    ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo]. [getTodayBirthday]
AS
BEGIN TRY
 declare @today datetime; 
 SET @today = GETDATE();--Get today's date
 DECLARE @day VARCHAR(2);
 SET @day =REPLACE(DAY(@today),0,'');
 DECLARE @month VARCHAR(2) ;
 SET @month = REPLACE(month(@today),0,'');
 DECLARE @year VARCHAR(4);
 SET @year = YEAR(@today);
 SELECT * FROM dbo.UserInfo WHERE REPLACE(DAY(CONVERT(DATETIME,Birthday )),0,'') = @day AND REPLACE(MONTH(CONVERT(DATETIME,Brithday)),0,'') = @ month AND Birthday IS NOT NULL 

 END TRY
 BEGIN CATCH
 ErrorLog -- Call the above procedure to save the error log.
 END CATCH


説明:ERROR_NUMBER(),ERROR_SEVERITY(),ERROR_STATE(),ERROR_PROCEDURE(),ERROR_LINE(),ERROR_MESSAGE() これらの関数はCatchの内部でのみ使用可能です