Рівень тяжкості 16
може припинити виконання.
ПОПРОБУЙТЕ УЛОВКИ з RAISERROR ():
RAISERROR()
з серйозністю 16 припиняє страту за все, що знаходиться нижче лінії правопорушення.
Однак це стосується лише перебування всередині блоку спробу.
RAISERROR (N'Before Try: Raise-Error 16.', 16, 0)
SELECT 'Before Try: Select.'[Marker]
BEGIN TRY
RAISERROR (N'Inside Try: Raise-Error 16.', 16, 0)
SELECT 'Inside Try: Select.'[Marker]
END TRY
BEGIN CATCH
RAISERROR (N'Inside Catch: Raise-Error 16.', 16, 0)
SELECT 'Inside Catch: Select.'[Marker]
END CATCH
RAISERROR (N'After Try-Catch: Raise-Error 16.', 16, 0)
SELECT 'After Try-Catch: Select.'[Marker]
Здивований? Так само, як і я.
Те, що мене також закинуло, не всі тяжкості 16 -ти однакові.
Якби ви прокоментували лінію Divide-By-Zero у самому верху, тоді нічого під нею не працюватиме.
Логіка Divide-By-Zero також генерує виняток важкості- 16 ,
але вона обробляється з повною зупинкою , на відміну від випадків, коли це відбувається RAISERROR()
.
Примітка: Використовуйте ;THROW
як останній рядок у блоці Catch-Block, щоб правильно
викинути виняток SQL для RAISERROR()
події, ініційованої вашим Try-Block.
Це фактично зупинить виконання з повною зупинкою. Кома потрібна , коли інші лінії існують в улові-Block перед викликом .
Якщо ваша логіка правильно обробляє помилку в блоці Catch-Block (і ви хотіли б продовжувати обробку
решти логіки після неї), тоді не використовуйте .
;
;THROW
;THROW
Висновок:
Не поєднуйте серйозність- 16, вироблену SQL-Server-Engine,
з такою, яку ви піднімаєте самостійно RAISERROR()
.
Для всіх намірів і цілей (при навмисному викиданні власних помилок) враховуйте лише 2 серйозності:
0 (для інформаційного або попереджувального) та
16 (для кидання винятку, який обробляється в рамках блоку спроб - щоб викинути його на блок блокування) .
Інформація зараз!
Примітка: Якщо ви використовуєте RAISERROR()
для відображення Інформаційних повідомлень,
то я пропоную використовувати WITH NOWAIT
:
RAISERROR('Read me right now!', 0, 1) WITH NOWAIT
RAISERROR('Read me whenever.' , 0, 1)
DECLARE @WaitSeconds Int = 10
DECLARE @WaitFor DateTime = DATEADD(SECOND, @WaitSeconds, 0)
WAITFOR DELAY @WaitFor
Це особливо корисно під час тривалих пакетних операцій, коли ви хочете отримати деяке розуміння
того, як все просувається, коли ви досягаєте певних етапових позначок протягом всієї партії.
При НЕ використанні WITH NOWAIT
, ви ніколи не знаєте , коли може з'явитися ваші інформаційні повідомлення.
Вони можуть з’являтися з перервами протягом всієї партії або відразу, коли партія завершується.