X_TEST 列が存在しないため、ここでエラーが発生することが予想されます。しかし、エラーは例外ブロックによってキャッチされていません。
BEGIN TRY
SELECT X_TEST FROM ACCOUNTS
END TRY
BEGIN CATCH
PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
なんで ?エラーの重大度のためですか?
X_TEST 列が存在しないため、ここでエラーが発生することが予想されます。しかし、エラーは例外ブロックによってキャッチされていません。
BEGIN TRY
SELECT X_TEST FROM ACCOUNTS
END TRY
BEGIN CATCH
PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
なんで ?エラーの重大度のためですか?
いいえ、TRY は独自のスコープ内で特定の種類のエラーのみを処理できます。ここで、次のようなストアド プロシージャがあるとします (non_existent_column
ドロップされた後)。
CREATE PROCEDURE dbo.blat
AS
BEGIN
BEGIN TRY
SELECT non_existent_column FROM dbo.table_that_exists;
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE();
END CATCH
END
GO
これだけやると…
EXEC dbo.blat;
...そのTRYのスコープ内のステートメントが解析に失敗するため、コンパイルエラーが発生します。
Msg 207, Level 16, State 1, Procedure fooblat, Line 5
Invalid column name 'non_existent_column'.
ただし、このエラーは外側のスコープでキャッチできます (プロシージャに含まれているかどうかに関係TRY/CATCH
なく)。
BEGIN TRY
EXEC dbo.fooblat;
END TRY
BEGIN CATCH
PRINT 'There was an error:';
PRINT ERROR_MESSAGE();
END CATCH
結果 (これは例外ではなく、テキストが赤くなくなっていることに注意してください):
There was an error:
Invalid column name 'non_existent_column'.
動的 SQL を使用してこれを回避することもできますが、すでにそれを撃ち落としているようです。そのため、これは私が考えることができる次善の提案です。つまり、外側のスコープでエラーをキャプチャします。
存在しない列を使用すると、構文エラーになります。あなたのバッチは決して実行を開始しません。
次のコードを検討してください。
BEGIN TRY
sdgedtju§$%&/()=
END TRY
BEGIN CATCH
PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
あなたはそれが始まることさえ期待していませんよね?コンパイルされません。存在しない列を使用することはまったく同じです
このコードは、期待していた動作を提供します...
BEGIN TRY
exec('SELECT X_TEST FROM ACCOUNTS')
END TRY
BEGIN CATCH
PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH