SQL Serverのバージョンに応じて、RAISERRORまたはTHROWを選択することはできますか?


11

これが私のコードです:

BEGIN TRY
INSERT INTO TABLE (F1,F2,F3) 
VALUES ('1','2','3')
END TRY
BEGIN CATCH
;THROW
END CATCH

SQL 2008が搭載されたマシンで実行しない限り、うまく機能します。CATCHブロックでSQLバージョンをチェックし、それが2012以上の場合はTHROWを実行し、2008の場合はRAISERRORを実行します。構文エラー、それが可能かどうか疑問に思っています。このような単純なものでさえ、私にはうまくいきません。

BEGIN CATCH
IF ((SELECT SERVERPROPERTY('productversion')) >= 11) ;THROW
END CATCH

任意のアドバイスをいただければ幸いです。

回答:


9

いいえ、これは不可能です。

これは以前のバージョンでは無効な構文であり、コンパイルエラーの原因になります。

パラメータなしのスローをキャッチ内に直接含める必要があるため、キャッチブロック内THROWでを非表示にすることもできませんEXEC

展開先のSQL Serverのバージョンに応じて、必要なコードバージョンを展開する必要があります(残念ながら、私が認識しているSSDTツールでは、これに対する適切なサポートはありません。コード行を選択的に含めることに相当するものはありません。条件付きコンパイル)


4

間の代替に技術的には可能であったとしても、それを指摘されるべきであるTHROWRAISERROR(ほとんど)あなたが実際にこれを行うにはしたくないだろう。どうして?パラメータなしの非常に気の利いた機能があるのでTHROW使用して再スローエラーすると同じメッセージ番号(すなわちMsg 8134代わりのMsg X場所X> = 50000)は、それらの間の唯一の違いはない:THROWバッチ中止しばらくはされませんRAISERROR。以下に示すように、これは重要な動作の違いになる可能性があります。

テスト設定

--DROP PROC ##Throw;
--DROP PROC ##RaisError;

GO
CREATE PROCEDURE ##Throw
AS
SET NOCOUNT ON;
BEGIN TRY
  SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
  THROW;
END CATCH;
SELECT 1 AS [AA];
GO

CREATE PROCEDURE ##RaisError
AS
SET NOCOUNT ON;
BEGIN TRY
  SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
  RAISERROR('test, yo!', 16, 1);
  -- RETURN; -- typically at end of CATCH block when using RAISERROR
END CATCH;
SELECT 2 AS [BB];
GO

テスト1

EXEC ##Throw;
SELECT 3 AS [CC];

戻り値:

"Results" Tab:

DivideByZero
{empty result set}

"Messages" Tab:

Msg 8134, Level 16, State 1, Procedure ##Throw, Line 38
Divide by zero error encountered.

テスト2

EXEC ##RaisError;
SELECT 4 AS [DD];

戻り値:

"Results" Tab:

DivideByZero
{empty result set}

BB
2

DD
4

"Messages" Tab:

Msg 50000, Level 16, State 1, Procedure ##RaisError, Line 45
test, yo!

公平を期すために、次のようにしてこの違いを隠すことができます。

  • 構成THROW内で使用するコードへのすべての呼び出しを常にラップしますTRY...CATCH(以下に示します)
  • THROW(まあ、を除いてEND CATCH;)の後にコードを配置しないでください

テスト3

BEGIN TRY
  EXEC ##Throw;
  SELECT 5 AS [EE];
END TRY
BEGIN CATCH
  SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 6 AS [FF];
GO

戻り値:

"Results" Tab:

DivideByZero
{empty result set}

ErrorNumber     ErrorMessage
8134            Divide by zero error encountered.

FF
6

テスト4

BEGIN TRY
  EXEC ##RaisError;
  SELECT 7 AS [GG];
END TRY
BEGIN CATCH
  SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 8 AS [HH];
GO

戻り値:

"Results" Tab:

DivideByZero
{empty result set}

ErrorNumber     ErrorMessage
50000           test, yo!

HH
8

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.