daftar galat batal membatalkan dalam SQL server

9

Dalam SQL Server, jika XACT_ABORT tidak aktif maka beberapa kesalahan akan menghentikan pernyataan saat ini (misalnya memasok jumlah parameter yang salah ke prosedur tersimpan yang mengambil beberapa parameter) dan beberapa kesalahan akan membatalkan seluruh batch (misalnya memasok parameter ke penyimpanan prosedur yang tidak mengambil parameter). [Referensi]: http://www.sommarskog.se/error-handling-I.html#scope-abortion .

Yang ingin saya ketahui adalah apakah ada daftar pasti yang mana kesalahan dibatalkan batch dan mana yang mengakhiri pernyataan.

Jamie Alford
sumber

Jawaban:

6

Saya percaya ada beberapa pengecualian, tetapi dari Database Engine Error Severities (MSDN) :

Pesan kesalahan dengan tingkat keparahan 19 atau lebih tinggi menghentikan pelaksanaan batch saat ini.

Kesalahan yang mengakhiri koneksi database, biasanya dengan tingkat keparahan dari 20 hingga 25, tidak ditangani oleh blok CATCH karena eksekusi dibatalkan ketika koneksi berakhir.

Jadi sepertinya Anda bisa mendapatkan daftar definitif dari kueri berikut (tentu saja ini tidak akan memungkinkan Anda untuk menyaring yang mana yang dapat disebabkan oleh pengguna T-SQL):

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

Di SQL Server 2012, ini menghasilkan 210 baris.

Di SQL Server 2016, ini menghasilkan 256 baris.

By the way, saya tidak percaya dua skenario yang Anda gambarkan dalam pertanyaan Anda bekerja seperti yang Anda pikirkan, setidaknya tidak dalam versi SQL Server modern. Saya mencoba ini pada 2012 dan 2016 (saya percaya artikel Erland menggambarkan perilaku SQL Server 2000, yang saya tidak ingat apakah itu berbeda, tetapi hari ini tidak terlalu relevan bahkan jika demikian).

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

Ini semua menghasilkan kesalahan tingkat keparahan 16, dan semuanya melanjutkan dengan batch, sebagaimana dibuktikan oleh hasil cetak:

Msg 8146, Level 16, Negara 2, Prosedur pA, Baris 11
Prosedur pA tidak memiliki parameter dan argumen diberikan.
### Prosedur panggilan yang tidak mengambil parameter dengan parameter
Msg 201, Level 16,
Status 4, Prosedur pB, Prosedur Baris 14 atau fungsi 'pB' mengharapkan parameter '@x', yang tidak disertakan.
### Prosedur panggilan yang mengambil 2 parameter tanpa parameter
Msg 201, Level 16,
Status 4, Prosedur pB, Prosedur 18 atau fungsi 'pB' mengharapkan parameter '@y', yang tidak disediakan.
### Prosedur panggilan yang mengambil 2 parameter dengan tidak cukup parameter
Msg 8144, Level 16, Status 2, Prosedur pB, Baris 22
Prosedur atau fungsi pB memiliki terlalu banyak argumen yang ditentukan.
### Prosedur panggilan yang mengambil 2 parameter dengan terlalu banyak parameter

Seperti yang saya duga, ada pengecualian, tentu saja, seperti yang tercantum dalam komentar. Kegagalan konversi adalah tingkat keparahan 16 tetapi membatalkan kumpulan:

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

Hasil tidak termasuk hasil cetak saat ini:

Msg 245, Level 16, Keadaan 1
Konversi gagal ketika mengonversi nilai varchar 'foo' ke int tipe data.

Aaron Bertrand
sumber
Terima kasih banyak! Saya pikir saya tidak akan dapat menggunakan tingkat keparahan sebagai indikator karena ketidakkonsistenan sebelumnya. Sangat senang mendengar bahwa bukan itu masalahnya.
Jamie Alford
Aargh! Masih ada beberapa kesalahan level 16 yang akan membatalkan bets. Jika saya memilih dan menjalankan: mulai tran print @@ TRANCOUNT konversi cetak (int, 'abc') diikuti oleh: print @@ TRANCOUNT Akan ada kesalahan level 16 tetapi bets akan dibatalkan.
Jamie Alford
BTW, jika Anda menemukan kasus-kasus di mana pengecualian dibesarkan dengan tingkat keparahan yang berbeda dari yang dinyatakan, harap laporkan melalui koneksi
Remus Rusanu
2

Selain jenis kesalahan yang dicatat oleh @ Harun (yaitu Tingkat Permasalahan > = 19 dan kegagalan konversi), jenis kesalahan berikut, yang dicatat di halaman MSDN untuk TRY ... CATCH , juga akan membatalkan bets:

Jenis kesalahan berikut ini tidak ditangani oleh blok CATCH ketika mereka terjadi pada tingkat eksekusi yang sama seperti konstruksi COB… CATCH:

  • Kompilasi kesalahan, seperti kesalahan sintaksis, yang mencegah batch berjalan.

  • Kesalahan yang terjadi selama kompilasi tingkat pernyataan, seperti kesalahan resolusi nama objek yang terjadi setelah kompilasi karena resolusi nama yang ditangguhkan.

Kesalahan ini dikembalikan ke tingkat yang menjalankan batch, prosedur tersimpan, atau pemicu.

Dalam contoh di bawah ini, harap dicatat bahwa tiga di antaranya bahkan Tingkat Keseriusan 15.

CONTOH 1

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

Pengembalian:

Msg 137, Level 15, State 2, Line 2
Harus mendeklarasikan variabel skalar "@NotDeclared".

CONTOH 2

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

Pengembalian:

Msg 102, Level 15, State 1, Line 2
Sintaks salah dekat 'InvalidSQL'.

CONTOH 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?';

Pengembalian:

Msg 102, Level 15, State 1, Line 3
Sintaks salah dekat '50505'.

CONTOH 4

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

Pengembalian:

Msg 207, Level 16, Negara 1, Baris 3
Nama kolom tidak valid 'NoSuchColumn'.

Solomon Rutzky
sumber