Thursday, October 18, 2018

Wyjątki


Niekiedy podczas wykonania pojawiają się sytuacje wyjątkowe, takie jak np. próba dzielenia przez zero, brak dostępu do pliku, próba odczytania nieistniejących danych etc.

do
$$
begin
raise notice '%',10/0;
end $$;


Próba wykonania powyższego kodu skończy się wyjątkiem - próbowałem wyświetlić wynik dzielenia 10 przez 0.




Mamy tu do czynienia z pojawieniem się wyjątku. W takiej sytuacji blok kodu jest przerywany, a na konsoli pojawia się komunikat błędu. Gdyby po linijce w której wyjątek następuje były kolejne działania, nie zostałyby one wykonane.

Możemy zareagować na pojawienie się takiego wyjątku dodając sekcję obsługi wyjątków:

do
$$
begin
raise notice '%',10/0;
raise notice 'Coś na koniec...';
exception
when division_by_zero then raise notice 'ej, nie można dzielić przez 0!';
end $$;

Sprowadza się to do dodania słówka exception na końcu kodu i dodania obsługi wyjątku. Jeśli nastąpi wyjątek dzielenia przez zero, zostanie on na poziomie tej sekcji obsłużony. Możemy w tym miejscu umieścić jakiś kod który np. wyświetli użytkownikowi stosowny komunikat zamiast kończyć program z błędem. Jak widać na powyższym screenie, linia z wyświetleniem tekstu "Coś na koniec" nadal się nie wykonała, ale wykonanie przesło do sekcji obsługi wyjątków i zostało wyświetlone przewidziane przez nas ostrzeżenie.
Może zaistnieć potrzeba obsłużenia wyjątku ale bez kończenia programu. Przykładowo chcielibyśmy wyświetlić użytkownikowi ostrzeżenie o braku możliwości dzielenia przez zero, ale kontynuować wykonanie programu. W takiej sytuacji możemy posłużyć się blokami zagnieżdżonymi:


do
$$
begin
begin
raise notice '%',10/0;
exception
when division_by_zero then raise notice 'ej, nie można dzielić przez 0!';
end;
raise notice 'Coś na koniec...';

end $$;


Blok zagnieżdżony to po prostu blok wbudowany w inny blok. Jak widzisz, blok zagnieżdżony może posiadać własną sekcję obsługi wyjątków. W tym przypadku objąłem problematyczną linijkę blokiem zagnieżdżonym z własną sekcją obsługi wyjątków. Dzięki takiemu zabiegowi, wyjątek został obsłużony na poziomie bloku zagnieżdżonego. Sam blok zagnieżdżony jako "podjednostka" zakończył się poprawnie, dzięki czemu nasz nadrzędny blok kodu jest wykonywany dalej. Możemy to zaobserwować dzięki wyświetleniu się "coś na koniec..." w konsoli.
Nie musimy wskazywać żadnego konkretnego wyjątku. Możemy posłużyć się klauzulą "when others" aby obsłużyć każdy pojawiający się wyjątek:

do
$$
begin
raise notice '%',10/0;
exception
when others then raise notice 'KLOPS!';

end $$;



Możemy również połączyć jedno z drugim w taki sposób, że dzielenie przez zero będzie obsługiwane w dedykowany sposób, a każdy inny wyjątek w sposób ogólny:


do
$$
begin
raise notice '%',10/0;
exception
when division_by_zero then raise notice 'nie dziel przez zero!';
when others then raise notice 'KLOPS!';
end $$;




Gdybyś potrzebował dobrać się do komunikatu lub kodu błędu (na przykład na potrzeby logowania pojawiających się wyjątków do osobnej tabeli) , możesz wykorzystać SQLERRM i SQLSTATE:


do
$$
begin
raise notice '%', 10/0;
exception
when others then
raise notice 'SQLERRM: %',SQLERRM;
raise notice 'SQLSTATE: %',SQLSTATE;
end $$;



No comments:

Post a Comment

Bezpłatny kurs PL/pgSQL by Andrzej Klusiewicz

Cześć  :) Oddaję w Wasze ręce wersję 1.0.0.0.0.(0) swojego tutoriala dotyczącego języka PL/pgSQL - czyli proceduralnego języka przetwarza...