Obsługa wyjątków Oracle PL/SQL (przykłady)
Co to jest obsługa wyjątków w PL/SQL?
Wyjątek występuje, gdy silnik PL/SQL napotka instrukcję, której nie może wykonać z powodu błędu występującego w czasie wykonywania. Błędy te nie zostaną przechwycone w czasie kompilacji, dlatego należy je obsłużyć tylko w czasie wykonywania.
Na przykład, jeśli silnik PL/SQL otrzyma instrukcję podzielenia dowolnej liczby przez „0”, wówczas silnik PL/SQL wyrzuci ją jako wyjątek. Wyjątek jest zgłaszany tylko w czasie wykonywania przez silnik PL/SQL.
Wyjątki spowodują dalsze wykonywanie programu, więc aby uniknąć takiego warunku, należy je przechwycić i obsłużyć oddzielnie. Proces ten nazywany jest obsługą wyjątków i programista obsługuje wyjątek, który może wystąpić w czasie wykonywania.
Składnia obsługi wyjątków
Wyjątki są obsługiwane na poziomie bloku, tzn. jeśli w dowolnym bloku wystąpi jakikolwiek wyjątek, wówczas część kontrolna tego bloku zakończy się wykonaniem. Wyjątek zostanie następnie obsłużony w części tego bloku obsługującej wyjątki. Po obsłużeniu wyjątku nie ma możliwości ponownego przesłania sterowania do sekcji wykonania tego bloku.
Poniższa składnia wyjaśnia, jak przechwycić i obsłużyć wyjątek.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
Wyjaśnienie składni:
- W powyższej składni blok obsługi wyjątku zawiera serię warunków WHEN do obsługi wyjątku.
- Po każdym warunku WHEN następuje nazwa wyjątku, który ma zostać wywołany w czasie wykonywania.
- Gdy w czasie wykonywania zostanie zgłoszony jakikolwiek wyjątek, silnik PL/SQL będzie szukać tego konkretnego wyjątku w części obsługującej wyjątki. Rozpocznie się od pierwszej klauzuli „WHEN” i będzie wyszukiwać sekwencyjnie.
- Jeśli znajdzie obsługę wyjątku dla zgłoszonego wyjątku, wykona tę konkretną część kodu obsługi.
- Jeśli dla zgłoszonego wyjątku nie ma żadnej klauzuli „WHEN”, silnik PL/SQL wykona część „WHEN OTHERS” (jeśli występuje). Jest to wspólne dla wszystkich wyjątków.
- Po wykonaniu wyjątku kontrola części wyjdzie z bieżącego bloku.
- W czasie wykonywania dla bloku można wykonać tylko jedną część wyjątku. Po jego wykonaniu kontroler pominie pozostałą część obsługi wyjątków i wyjdzie z bieżącego bloku.
Uwaga: KIEDY INNE powinny zawsze znajdować się na ostatniej pozycji sekwencji. Część obsługi wyjątków występująca po WHEN OTHERS nigdy nie zostanie wykonana, ponieważ sterowanie wyjdzie z bloku po wykonaniu WHEN OTHERS.
Rodzaje wyjątków
Istnieją dwa rodzaje wyjątków w PL/SQL.
- Predefiniowane wyjątki
- Wyjątek zdefiniowany przez użytkownika
Predefiniowane wyjątki
Oracle zdefiniował jakiś typowy wyjątek. Te wyjątki mają unikalną nazwę wyjątku i numer błędu. Wyjątki te są już zdefiniowane w pakiecie STANDARD w Oracle. W kodzie możemy bezpośrednio użyć tych predefiniowanych nazw wyjątków do ich obsługi.
Poniżej znajduje się kilka predefiniowanych wyjątków
Wyjątek | Kod błędu | Powód wyjątku |
---|---|---|
ACCESS_INTO_NULL | ORA-06530 | Przypisz wartość do atrybutów niezainicjowanych obiektów |
CASE_NOT_FOUND | ORA-06592 | Żadna z klauzul „WHEN” w instrukcji CASE nie jest spełniona i nie określono żadnej klauzuli „ELSE”. |
KOLEKCJA_IS_NULL | ORA-06531 | Używanie metod kolekcji (z wyjątkiem EXISTS) lub uzyskiwanie dostępu do atrybutów kolekcji w niezainicjowanych kolekcjach |
CURSOR_ALREADY_OPEN | ORA-06511 | Próbuję otworzyć plik kursor który jest już otwarty |
DUP_VAL_ON_INDEX | ORA-00001 | Przechowywanie zduplikowanej wartości w kolumnie bazy danych, która jest ograniczona unikalnym indeksem |
INVALID_CURSOR | ORA-01001 | Nielegalne operacje kursora, takie jak zamykanie nieotwartego kursora |
NIEPRAWIDŁOWY NUMER | ORA-01722 | Konwersja znaku na liczbę nie powiodła się z powodu nieprawidłowego znaku liczby |
NIE ZNALEZIONO DANYCH | ORA-01403 | Kiedy instrukcja „SELECT” zawierająca klauzulę INTO nie pobiera żadnych wierszy. |
WIERSZ_MISMATCH | ORA-06504 | Gdy typ danych zmiennej kursora jest niezgodny z rzeczywistym typem powrotu kursora |
SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Odwoływanie się do kolekcji za pomocą numeru indeksu większego niż rozmiar kolekcji |
SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Odwoływanie się do kolekcji przez numer indeksu spoza dozwolonego zakresu (np.: -1) |
TOO_MANY_ROWS | ORA-01422 | Gdy instrukcja „SELECT” z klauzulą INTO zwraca więcej niż jeden wiersz |
WARTOŚĆ_BŁĄD | ORA-06502 | Błąd arytmetyczny lub ograniczenie rozmiaru (np. przypisanie wartości do zmiennej, która jest większa niż rozmiar zmiennej) |
ZERO_DIVIDE | ORA-01476 | Dzielenie liczby przez „0” |
Wyjątek zdefiniowany przez użytkownika
In Oracle, poza wcześniej zdefiniowanymi wyjątkami, programista może utworzyć własny wyjątek i obsłużyć go. Można je tworzyć na poziomie podprogramu w części deklaracyjnej. Wyjątki te są widoczne tylko w tym podprogramie. Wyjątek zdefiniowany w specyfikacji pakietu jest wyjątkiem publicznym i jest widoczny wszędzie tam, gdzie pakiet jest dostępny.
Składnia: Na poziomie podprogramu
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- W powyższej składni zmienna „nazwa_wyjątku” jest zdefiniowana jako typ „WYJĄTEK”.
- Można tego użyć w podobny sposób, jak predefiniowany wyjątek.
Składnia:Na poziomie specyfikacji pakietu
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- W powyższej składni zmienna „nazwa_wyjątku” jest zdefiniowana jako typ „WYJĄTEK” w specyfikacji pakietu .
- Można tego użyć w bazie danych, gdziekolwiek można wywołać pakiet „nazwa_pakietu”.
Wyjątek zgłoszenia PL/SQL
Wszystkie predefiniowane wyjątki są zgłaszane niejawnie za każdym razem, gdy wystąpi błąd. Jednak wyjątki zdefiniowane przez użytkownika muszą zostać jawnie zgłoszone. Można to osiągnąć za pomocą słowa kluczowego „RAISE”. Można tego użyć na dowolny ze sposobów wymienionych poniżej.
Jeśli w programie osobno użyto opcji „RAISE”, wówczas zgłoszony już wyjątek zostanie rozpropagowany do bloku nadrzędnego. Tylko w bloku wyjątku można użyć, jak pokazano poniżej.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Wyjaśnienie składni:
- W powyższej składni słowo kluczowe RAISE jest użyte w bloku obsługi wyjątków.
- Ilekroć program napotka wyjątek „nazwa_wyjątku”, wyjątek zostanie obsłużony i zakończy się normalnie
- Jednak słowo kluczowe „RAISE” w części dotyczącej obsługi wyjątków spowoduje propagację tego konkretnego wyjątku do programu nadrzędnego.
Uwaga: Podczas zgłaszania wyjątku do bloku nadrzędnego, zgłaszany wyjątek powinien być również widoczny w bloku nadrzędnym. W przeciwnym razie Oracle zgłosi błąd.
- Możemy użyć słowa kluczowego „RAISE”, po którym następuje nazwa wyjątku, aby zgłosić ten konkretny wyjątek zdefiniowany przez użytkownika/predefiniowany. Można tego użyć zarówno w części wykonawczej, jak i w części obsługującej wyjątki, aby zgłosić wyjątek.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Wyjaśnienie składni:
- W powyższej składni w części wykonawczej użyte jest słowo kluczowe RAISE, po którym następuje wyjątek „nazwa_wyjątku”.
- Spowoduje to zgłoszenie tego konkretnego wyjątku w momencie wykonania i należy się tym zająć lub zgłosić dalej.
1 przykład: W tym przykładzie zobaczymy
- Jak zadeklarować wyjątek
- Jak podnieść zadeklarowany wyjątek i
- Jak propagować to do głównego bloku
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line(‘Inside nested block’); Dbms_output.put_line(‘Raising sample_exception from nested block’); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in nested block. Raising to main block’); RAISE, END; BEGIN Dbms_output.put_line(‘Inside main block’); Dbms_output.put_line(‘Calling nested block’); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in main block'); END: /
Wyjaśnienie kodu:
- Linia kodu 2: Deklarowanie zmiennej „wyjątek_przykładowy” jako typu WYJĄTKU.
- Linia kodu 3: Deklarowanie procedury zagnieżdżonej_bloku.
- Linia kodu 6: Drukowanie instrukcji „Wewnątrz zagnieżdżonego bloku”.
- Linia kodu 7: Drukowanie instrukcji „Podnoszenie wyjątku_próbki z zagnieżdżonego bloku”.
- Linia kodu 8: Zgłaszanie wyjątku za pomocą „RAISE sample_exception”.
- Linia kodu 10: Procedura obsługi wyjątku dla wyjątku przykładowy_wyjątek w zagnieżdżonym bloku.
- Linia kodu 11: Drukowanie instrukcji „Wyjątek przechwycony w zagnieżdżonym bloku. Podniesienie do głównego bloku”.
- Linia kodu 12: Zgłaszanie wyjątku do głównego bloku (propagowanie do głównego bloku).
- Linia kodu 15: Drukowanie zestawienia „Wewnątrz głównego bloku”.
- Linia kodu 16: Wydrukowanie instrukcji „Wywołanie bloku zagnieżdżonego”.
- Linia kodu 17: Wywołanie procedury zagnieżdżonej_bloku.
- Linia kodu 18: Wyjątek
- Linia kodu 19: Procedura obsługi wyjątku dla wyjątku sample_exception w głównym bloku.
- Linia kodu 20: Drukowanie instrukcji „Wyjątek przechwycony w bloku głównym”.
Ważne punkty, na które należy zwrócić uwagę w wyjątku
- W funkcji wyjątek powinien zawsze zwracać wartość lub dalej zgłaszać wyjątek. w przeciwnym razie Oracle w czasie wykonywania zgłosi błąd „Funkcja zwrócona bez wartości”.
- Instrukcje kontroli transakcji można podać w bloku obsługi wyjątków.
- SQLERRM i SQLCODE to wbudowane funkcje, które wyświetlają komunikat i kod wyjątku.
- Jeśli wyjątek nie zostanie obsłużony, domyślnie wszystkie aktywne transakcje w tej sesji zostaną wycofane.
- RAISE_APPLICATION_ERROR (- , ) można użyć zamiast RAISE, aby zgłosić błąd za pomocą kodu użytkownika i komunikatu. Kod błędu powinien być większy niż 20000 i poprzedzony znakiem „-”.
Podsumowanie
Po przeczytaniu tego rozdziału powinieneś być w stanie pracować nad następującymi aspektami Pl SQL wyjątki
- Obsługa wyjątków
- Zdefiniuj wyjątek
- Podnieś wyjątek
- Propagacja wyjątków