Paweł Łukasiewicz
2017-09-01
Paweł Łukasiewicz
2017-09-01
Wprowadzenie
W tym artykule skupię się na podstawach obsługi błędów za pomocą bloku TRY CATCH, który został wprowadzony w SQL Server 2005. Opiszę podstawowe funkcje do zwracania informacji dotyczących błędów oraz pokaże jak używać bloku TRY CATCH w procedurach składowanych i transakcjach.
SQL Server używa poniższej składni do przechwytywania wyjątków:
BEGIN TRY
SELECT [FIRST] = 1
SELECT [SECOND] = 1/0
SELECT [THIRD] = 3
END TRY
BEGIN CATCH
PRINT 'An error occurred'
END CATCH
Wywołanie spowoduje zwrócenie następującego wyniku:
-- (1 row(s) affected)
--
-- (0 row(s) affected)
-- An error occurred
Kluczową różnicą w porównaniu do SQL Server 2000 jest zatrzymanie wykonywania instrukcji. W nowszych wersjach realizacja zadania przenosi się do bloku CATCH. Ten błąd nie jest zwracany do aplikacji klienckiej lub programu wywołującego.
Funkcje błędów
Wewnątrz bloku TRY CATCH znajduje się szereg wyspecjalizowanych funkcji służących do zwracania informacji o błędzie:
BEGIN TRY
SELECT [FIRST] = 1/0
END TRY
BEGIN CATCH
SELECT
[ErrorLine] = ERROR_LINE(),
[ErrorNumber] = ERROR_NUMBER(),
[ErrorSeverity] = ERROR_SEVERITY(),
[ErrorState] = ERROR_STATE(),
[ErrorMessage] = ERROR_MESSAGE()
END CATCH
Tak prezentują się zwracane informacje:
-- FIRST
-- -----------
--
-- (0 row(s) affected)
--
-- Error_Line Error_Number Error_Severity Error_State ErrorMessage
-- --------- ------------ -------------- ----------- -------------
-- 2 8134 16 1 Divide by zero error encountered.
--
-- (1 row(s) affected)
Poniżej lista funkcji, które możesz wykorzystać w bloku CATCH. Funkcję te zwracają wartość NULL jeżeli będą wywołane poza tym blokiem.
-
ERROR_NUMBER - liczba wystąpień błędu. Podobne do parametru @@ERROR z tym, że zwraca ten sam numer przez cały czas trwania bloku CATCH;
-
ERROR_MESSAGE - pełny tekst komunikatu o błędzie zawierający wszystkie parametry, np. nazwa obiektu;
-
ERROR_LINE - numer linii w której pojawił się błąd;
-
ERROR_SEVERITY - rygor zgłoszonego błędu. Blok CATCH zostaje użyty jeżeli zgłoszony błąd ma numer 11 lub większy. Poziom błędów od 11 do 16 oznacza zwykle błędy użytkownika lub kodu. Poziom 17 do 25 to zwykle błędy oprogramowania lub sprzętu w przypadku których dalsze wykonywanie instrukcji nie jest możliwe;
-
ERROR_STATE - czasami używane przez system do zwrócenia większej liczby informacji o błędzie.
-
ERROR_PROCEDURE - jeżeli błąd został wygenerowany wewnątrz procedury składowej będzie to jej nazwa.
Wyłapywanie błędów w procedurach składowanych
Blok TRY CATCH może wyłapywać błędy w procedurach składowanych wywoływanych prze inne procedury skadowane. Przykład:
BEGIN TRY
EXEC ParentError
END TRY
BEGIN CATCH
SELECT ErroLine = ERROR_LINE(),
ErrorProc = ERROR_PROCEDURE()
END CATCH
Na potrzeby powyższego przykładu zakładamy, że procedura ParrentError wywołuje procedurę ChildError, która generuje błąd. Wówczas zobaczymy poniższy komunikat:
-- Error_Line Error_Proc
-- ----------- -------------
-- 5 ChildError
Obsługa błędów a transakcje
Blok TRY CATCH działa również z transakcjami. Poniżej przedstawiam ogólny wzór użycia tego bloku wewnątrz procedur składowanych dla transakcji. Wszystkie błędy powodują operację cofnięcia instrukcji wykonanych w ramach transakcji.
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO Person.Address (AddressLine1,AddressLine2)
VALUES ('AddressLine1', 'AddressLine2')
INSERT INTO Person.AddressType (Name)
VALUES ('AddresTypeTest')
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
-- dodaj obsługę błędów:
SELECT [Error_Line] = ERROR_LINE(),
[Error_Number] = ERROR_NUMBER(),
[Error_Severity] = ERROR_SEVERITY(),
[Error_State] = ERROR_STATE(),
[Error_Message] = ERROR_MESSAGE()
END CATCH
Wywołanie zwróci błąd spowodowany próbą dodania wartości NULL do kolumny City.