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


9

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

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

回答:


6

いくつかの例外はあると思いますが、データベースエンジンエラーの重大度(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にはパラメータがなく、引数が指定されました。
###パラメータ
Msg 201、レベル16、状態4、プロシージャpB、行14の パラメータをとらないプロシージャの呼び出し
プロシージャまたは関数 'pB'は、指定されていないパラメータ '@x'を予期しています。
###パラメータなしの2つのパラメータを取るプロシージャを呼び出す
Msg 201、レベル16、状態4、プロシージャpB、行18
プロシージャまたは関数 'pB'には、指定されていないパラメータ '@y'が必要です。
### 2つのパラメーターを必要とする2つのパラメーターを取るプロシージャを呼び出す
Msg 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に変換するときに失敗しました。


どうもありがとうございました!以前は矛盾があったため、重大度レベルを指標として使用することはできないと思いました。そうではないと聞いてとても嬉しいです。
Jamie Alford、2016年

ああ!バッチを中止する重大度レベル16のエラーがまだいくつかあります。選択して実行した場合:begin tran print @@ TRANCOUNT print convert(int、 'abc')続いて:print @@ TRANCOUNTレベル16エラーが発生しますが、バッチは中止されます。
Jamie Alford、2016年

ところで、宣言されたものとは異なる重大度で例外が発生するケースを発見した場合は、接続を介してそれらを報告してください
Remus Rusanu

2

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

次のタイプのエラーは、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'。

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