список помилок переривання партії на 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 рядків.

До речі, я не вважаю, що два сценарії, які ви описуєте у своєму питанні, працюють так, як ви думаєте, принаймні, не в сучасних версіях SQL Server. Я спробував це і в 2012, і в 2016 (я вважаю, що стаття Ерланда описує поведінку 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 параметри з недостатньою кількістю параметрів
Msg 8144, Рівень 16, Стан 2, Процедура pB, Рядок 22
Процедура або функція pB задано занадто багато аргументів.
### Процедура виклику, яка приймає 2 параметри із занадто великою кількістю параметрів

Як я підозрював, звичайно, є винятки, як зазначено в коментарях. Невдача конверсії - це ступінь тяжкості 16, але перериває партію:

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

Результати цього разу не включають вихід друку:

Msg 245, рівень 16, стан 1
Перетворення не вдалося при перетворенні значення varchar 'foo' у тип даних int.


Дуже дякую! Я думав, що не зможу використовувати рівень вираженості як показник через попередню невідповідність. Дуже рада почути, що це не так.
Джеймі Алфорд

Аарх! Є ще деякі помилки рівня 16 суворості, які припинять партію. Якщо я виберу і виконую: start tran print @@ TRANCOUNT print convert (int, 'abc') з наступним: print @@ TRANCOUNT Буде помилка 16 рівня, але партія буде перервана.
Джеймі Алфорд

До речі, якщо ви виявите випадки, коли виняток порушений з
різкою сутністю

2

На додаток до типів помилок, відмічених @Aaron (тобто серйозність > = 19 та збої в конверсії), наступні типи помилок, зазначені на сторінці MSDN для TRY ... CATCH , також будуть скасовувати партію:

Наступні типи помилок не обробляються блоком CATCH, коли вони трапляються на тому ж рівні виконання, що і конструкція TRY… CATCH:

  • Помилки компіляції, такі як синтаксичні помилки, що запобігають запуску пакету.

  • Помилки, що виникають під час перекомпіляції рівня висловлювань, такі як помилки дозволу імені об'єкта, які виникають після компіляції через відкладене дозвіл імені.

Ці помилки повертаються до рівня, на якому виконувалася партія, збережена процедура або тригер.

У наведених нижче прикладах зауважте, що три з них - рівень рівності 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
Неправильний синтаксис біля "Недійсний SQL".

ПРИКЛАД 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".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.