web-dev-qa-db-ja.com

SQLサーバーのバッチ中止エラーのリスト

SQL Serverでは、XACT_ABORTがオフの場合、一部のエラーが現在のステートメントを終了し(たとえば、一部のパラメーターを受け取るストアドプロシージャに誤った数のパラメーターを提供する)、一部のエラーがバッチ全体を中止します(たとえば、ストアードにパラメーターを提供する)パラメータをとらない手続き)。 [参照]: http://www.sommarskog.se/error-handling-I.html#scope-abortion

私が知りたいのは、どのエラーがバッチアボートであり、どのエラーがステートメントの終了であるかの明確なリストがあるかどうかです。

9
Jamie Alford

いくつかの例外はあると思いますが、 データベースエンジンエラーの重大度(MSDN) から:

重大度レベルが19以上のエラーメッセージは、現在のバッチの実行を停止します。

通常は重大度が20〜25のデータベース接続を終了するエラーは、接続が終了すると実行が中止されるため、CATCHブロックでは処理されません。

したがって、次のクエリから決定的なリストを取得できるようです(もちろん、これでは、ユーザーT-SQLが原因である可能性があるものをフィルターで除外することはできません)。

SELECT message_id, severity, [text]
FROM sys.messages
WHERE language_id = 1033 
AND severity >= 19
ORDER BY severity, message_id;

SQL Server 2012では、これにより210行が生成されます。

SQL Server 2016では、これにより256行が生成されます。

ちなみに、あなたが質問で説明した2つのシナリオが、少なくとも最新バージョンのSQL Serverでは、あなたが思うように機能するとは思わない。私は2012年と2016年の両方でこれを試しました(Erlandの記事ではSQL Server 2000の動作について説明していると思いますが、違いがあったかどうかは覚えていませんが、今日でもそれほど関係はありません)。

USE tempdb;
GO

CREATE PROCEDURE dbo.pA -- no parameters
AS PRINT 1
GO
CREATE PROCEDURE dbo.pB -- two parameters
@x INT, @y INT
AS PRINT 1
GO

SET XACT_ABORT OFF;
GO

EXEC dbo.pA @foo = 1; 
PRINT '### Calling procedure that doesn''t take parameters with a parameter';
GO

EXEC dbo.pB; 
PRINT '### Calling procedure that takes 2 parameters with no parameters';
GO

EXEC dbo.pB @x = 1; 
PRINT '### Calling procedure that takes 2 parameters with not enough parameters';
GO

EXEC dbo.pB @x = 1, @y = 2, @z = 3; 
PRINT '### Calling procedure that takes 2 parameters with too many parameters';
GO

これらはすべて重大度レベル16のエラーを生成し、それらすべては印刷出力によって証明されるようにバッチを続行します。

メッセージ8146、レベル16、状態2、手順pA、行11
手順pAにはパラメーターがなく、引数が指定されました。
###パラメータを引数に取らない手続きの呼び出し
メッセージ201、レベル16、状態4、手順pB、行14
プロシージャまたは関数 'pB'には、指定されていないパラメータ '@x'が必要です。
###パラメータなしで2つのパラメータを取るプロシージャの呼び出し
メッセージ201、レベル16、状態4、手順pB、行18
プロシージャまたは関数 'pB'には、パラメータ '@y'が必要ですが、指定されていません。
###パラメータが不十分で2つのパラメータを取るプロシージャの呼び出し
メッセージ8144、レベル16、状態2、手順pB、行22
プロシージャまたは関数pBに指定された引数が多すぎます。
###パラメータが多すぎる2つのパラメータを取るプロシージャの呼び出し

私が疑ったように、コメントで述べられているように、もちろん例外があります。変換の失敗は重大度16ですが、バッチを中止します:

SET XACT_ABORT OFF;
SELECT CONVERT (INT, 'foo');
PRINT 'Made it.'; -- no print happens

今回の結果には、印刷出力は含まれていません。

メッセージ245、レベル16、状態1
varchar値 'foo'をデータ型intに変換するときに変換が失敗しました。

6
Aaron Bertrand

エラーのタイプに加えて @ Aaronによって示される (つまり、重大度> = 19および変換エラー)、MSDNページの TRY ... CATCHに記載されているエラーのタイプ) 、バッチも中止します:

次のタイプのエラーは、TRY…CATCHコンストラクトと同じ実行レベルで発生した場合、CATCHブロックでは処理されません。

  • 構文エラーなど、バッチの実行を妨げるコンパイルエラー。

  • 名前解決の遅延のためにコンパイル後に発生するオブジェクト名解決エラーなど、ステートメントレベルの再コンパイル中に発生するエラー。

これらのエラーは、バッチ、ストアドプロシージャ、またはトリガーを実行したレベルに戻されます。

以下の例では、そのうちの3つが重大度レベル15であることに注意してください。

例1

SET XACT_ABORT OFF;
SELECT @NotDeclared; -- parse error
PRINT 'Do you see me?';

戻り値:

メッセージ137、レベル15、状態2、行2
スカラー変数「@NotDeclared」を宣言する必要があります。

例2

SET XACT_ABORT OFF;
InvalidSQL; -- parse error
PRINT 'Do you see me?';

戻り値:

メッセージ102、レベル15、状態1、行2
「InvalidSQL」付近の構文が正しくありません。

例3

SET XACT_ABORT OFF;
SELECT 1 -- statement preceding THROW not terminated by semicolon
THROW 50505, N'Error, yo', 1; -- parse error
PRINT 'Do you see me?';

戻り値:

メッセージ102、レベル15、状態1、行3
「50505」付近の構文が正しくありません。

例4

SET XACT_ABORT OFF;
SELECT NoSuchColumn FROM sys.objects; -- compilation error
PRINT 'Do you see me?';

戻り値:

メッセージ207、レベル16、状態1、行3
無効な列名「NoSuchColumn」。

2
Solomon Rutzky