Obsługa wyjątków Oracle PL/SQL (przykłady)
⚡ Inteligentne podsumowanie
Obsługa wyjątków w Oracle Język PL/SQL przechwytuje błędy czasu wykonania, które zatrzymują wykonywanie bloku, umożliwiając silnikowi przekazanie kontroli do sekcji WYJĄTKÓW, w której wstępnie zdefiniowane, zdefiniowane przez użytkownika i inne procedury obsługi reagują, zgłaszają lub bezpiecznie propagują błędy.

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 są wykrywane w czasie kompilacji i dlatego muszą być obsłużone dopiero w czasie wykonywania.
Na przykład, jeśli silnik PL/SQL otrzyma instrukcję dzielenia liczby przez zero, zgłasza błąd jako wyjątek. Wyjątek jest zgłaszany przez silnik PL/SQL tylko w czasie wykonywania.
Wyjątek uniemożliwia dalsze wykonywanie programu, dlatego aby uniknąć takiej sytuacji, błąd musi zostać przechwycony i obsłużony osobno. Proces ten nazywa się obsługą wyjątków, w której programista obsługuje błąd, który może wystąpić w czasie wykonywania.
Składnia obsługi wyjątków
Wyjątki są obsługiwane na poziomie bloku. Po wystąpieniu wyjątku w bloku sterowanie opuszcza część wykonawczą tego bloku, a wyjątek jest następnie obsługiwany w części bloku przeznaczonej do obsługi wyjątków. Po obsłużeniu wyjątku sterowanie nie może powrócić do sekcji wykonawczej tego samego bloku.
Poniższa ilustracja pokazuje, jak sekcja wykonywania i sekcja obsługi wyjątków znajdują się w jednym bloku PL/SQL:
Poniższa składnia wyjaśnia, jak wychwycić 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ątków zawiera serię warunków WHEN służących do obsługi wyjątków.
- Po każdym warunku WHEN następuje nazwa wyjątku, który ma zostać zgłoszony w czasie wykonywania.
- Gdy w czasie wykonywania wystąpi wyjątek, silnik PL/SQL przeszukuje część obsługującą wyjątki w celu znalezienia tego konkretnego wyjątku, rozpoczynając od pierwszej klauzuli WHEN i przechodząc sekwencyjnie.
- Jeżeli znajdzie procedurę obsługi zgłoszonego wyjątku, wykonuje konkretny kod procedury obsługi.
- Jeśli żadna klauzula WHEN nie pasuje do zgłoszonego wyjątku, silnik PL/SQL wykonuje część WHEN OTHERS, jeśli jest obecna. Ta procedura obsługi jest wspólna dla wszystkich wyjątków.
- Po uruchomieniu modułu obsługi sterowanie opuszcza bieżący blok.
- Tylko jeden moduł obsługi wyjątków może być uruchomiony dla bloku w czasie wykonywania. Po jego uruchomieniu silnik pomija pozostałe moduły obsługi wyjątków i opuszcza bieżący blok.
Uwaga: Instrukcja WHEN OTHERS powinna zawsze być umieszczana na końcu sekwencji. Żaden handler napisany po instrukcji WHEN OTHERS nigdy się nie uruchamia, ponieważ sterowanie opuszcza blok po wykonaniu instrukcji WHEN OTHERS.
Rodzaje wyjątków
Istnieją dwa rodzaje wyjątków PL / SQL.
- Predefiniowane wyjątki
- Wyjątki zdefiniowane przez użytkownika
Predefiniowane wyjątki
Oracle ma predefiniowane kilka typowych wyjątków. Każdy predefiniowany wyjątek ma unikalną nazwę i numer błędu, a wszystkie są zadeklarowane w pakiecie STANDARD w OracleW kodzie można używać tych predefiniowanych nazw wyjątków bezpośrednio do obsługi odpowiadających im błędów. Wiele z nich jest bezpośrednio odwzorowywanych na typowe SQL błędy, które spotykają Cię każdego dnia.
Poniżej przedstawiono kilka wstępnie zdefiniowanych wyjątków:
| Wyjątek | Błąd Code | Powód wyjątku |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Przypisywanie wartości atrybutom niezainicjowanego obiektu |
| CASE_NOT_FOUND | ORA-06592 | Żadna z klauzul WHEN w poleceniu CASE nie jest spełniona i nie określono żadnej klauzuli ELSE |
| KOLEKCJA_IS_NULL | ORA-06531 | Korzystanie z metod kolekcji (oprócz EXISTS) lub uzyskiwanie dostępu do atrybutów kolekcji w niezainicjowanej kolekcji |
| 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 ograniczonej 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 numerycznego |
| NIE ZNALEZIONO DANYCH | ORA-01403 | Instrukcja SELECT zawierająca klauzulę INTO nie pobiera żadnych wierszy |
| WIERSZ_MISMATCH | ORA-06504 | Typ danych zmiennej kursora jest niezgodny z rzeczywistym typem zwracanym przez kursor |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Odwoływanie się do zbioru za pomocą numeru indeksu większego niż rozmiar zbioru |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Odwoływanie się do zbioru za pomocą numeru indeksu spoza dozwolonego zakresu (na przykład -1) |
| TOO_MANY_ROWS | ORA-01422 | Instrukcja SELECT z klauzulą INTO zwraca więcej niż jeden wiersz |
| WARTOŚĆ_BŁĄD | ORA-06502 | Błąd arytmetyczny lub błąd ograniczenia rozmiaru (na przykład przypisanie wartości większej niż rozmiar zmiennej) |
| ZERO_DIVIDE | ORA-01476 | Dzielenie liczby przez zero |
Wyjątek zdefiniowany przez użytkownika
Oprócz predefiniowanych wyjątków wymienionych powyżej, programista może tworzyć własne wyjątki i obsługiwać je. Są one tworzone na poziomie podprogramu w części deklaracyjnej i widoczne tylko w obrębie tego podprogramu. Wyjątek zdefiniowany w specyfikacji pakietu jest wyjątkiem publicznym i jest widoczny wszędzie tam, gdzie można uzyskać dostęp do pakietu.
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 „exception_name” jest zdefiniowana jako typ EXCEPTION.
- Następnie można go używać w taki sam sposób, jak predefiniowanego wyjątku.
Składnia: Na poziomie specyfikacji pakietu
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- W powyższej składni zmienna „exception_name” jest zdefiniowana jako typ WYJĄTKU w specyfikacji pakietu .
- Można go używać w całej bazie danych, wszędzie tam, gdzie można wywołać pakiet „package_name”.
Wyjątek zgłoszenia PL/SQL
Wszystkie predefiniowane wyjątki są zgłaszane domyślnie za każdym razem, gdy wystąpi odpowiadający im błąd. Wyjątki zdefiniowane przez użytkownika muszą być jednak zgłaszane jawnie za pomocą słowa kluczowego RAISE. Wyjątek RAISE można wykorzystać w sposób pokazany poniżej.
Jeśli polecenie RAISE zostanie użyte samodzielnie w procedurze obsługi wyjątku, przekaże ono zgłoszony już wyjątek do bloku nadrzędnego. Można go użyć tylko wewnątrz bloku wyjątku, jak pokazano poniżej.
Poniższy zrzut ekranu przedstawia instrukcję RAISE użytą samodzielnie do ponownego zgłoszenia wyjątku dla bloku otaczającego:
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 używane jest wewnątrz bloku obsługi wyjątków.
- Za każdym razem, gdy program napotka wyjątek „exception_name”, wyjątek jest obsługiwany i kończy działanie normalnie.
- Słowo kluczowe RAISE w procedurze obsługi wyjątek propaguje następnie ten sam wyjątek do programu nadrzędnego.
Uwaga: Podczas zgłaszania wyjątku w bloku nadrzędnym, zgłaszany wyjątek musi być również widoczny w bloku nadrzędnym; w przeciwnym razie Oracle wyrzuca błąd.
Można również użyć słowa kluczowego RAISE, po którym następuje nazwa wyjątku, aby zgłosić konkretny wyjątek zdefiniowany przez użytkownika lub predefiniowany. Ta forma może być używana zarówno w części wykonawczej, jak i w części obsługi wyjątku.
Poniższy zrzut ekranu przedstawia polecenie RAISE, po którym następuje nazwa wyjątku powodująca wygenerowanie konkretnego wyjątku:
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 słowo kluczowe RAISE używane jest w części wykonawczej, po którym następuje wyjątek „exception_name”.
- Spowoduje to wygenerowanie konkretnego wyjątku w czasie wykonywania, który następnie należy obsłużyć lub zgłosić ponownie.
1 przykład: W tym przykładzie zobaczymy:
- Jak zadeklarować wyjątek
- Jak zgłosić zadeklarowany wyjątek
- Jak propagować to do głównego bloku
Poniższy zrzut ekranu pokazuje cały blok, który deklaruje wyjątek sample_exception, zgłasza go wewnątrz zagnieżdżonego bloku i propaguje do bloku głównego:
Poniższy zrzut ekranu pokazuje ciąg dalszy tego samego przykładu, w którym blok główny w końcu przechwytuje propagowany wyjątek:
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; /
Code Wyjaśnienie:
- Code linia 2: Deklarowanie zmiennej „sample_exception” jako typu WYJĄTKOWEGO.
- Code linia 3: Deklarowanie procedury nested_block.
- Code linia 6: Wydrukowanie komunikatu „Wewnątrz zagnieżdżonego bloku”.
- Code linia 7: Wyświetlanie polecenia „Podnoszenie sample_exception z zagnieżdżonego bloku”.
- Code linia 8: Zgłaszanie wyjątku za pomocą „RAISE sample_exception”.
- Code linia 10: Obsługujący wyjątki sample_exception program w zagnieżdżonym bloku.
- Code linia 11: Wydrukowanie komunikatu „Wyjątek przechwycony w zagnieżdżonym bloku. Zgłoszenie do bloku głównego”.
- Code linia 12: Zgłoszenie wyjątku do bloku głównego (rozpowszechnianie go).
- Code linia 15: Wydruk komunikatu „Wewnątrz bloku głównego”.
- Code linia 16: Wydrukowanie instrukcji „Wywołanie bloku zagnieżdżonego”.
- Code linia 17: Wywołanie procedury nested_block.
- Code linia 19: Procedura obsługi wyjątku dla wyjątku sample_exception w głównym bloku.
- Code linia 20: Wydruk komunikatu „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 zawsze powinien albo zwrócić wartość, albo wywołać kolejny wyjątek; w przeciwnym razie Oracle zgłasza błąd „Funkcja zwrócona bez wartości” w czasie wykonywania.
- Oświadczenia dotyczące kontroli transakcji można wydać wewnątrz bloku obsługi wyjątków.
- SQLERRM i SQLCODE to wbudowane funkcje, które zwracają odpowiednio komunikat wyjątku i kod wyjątku.
- Jeśli wyjątek nie zostanie obsłużony, domyślnie wszystkie aktywne transakcje w danej sesji zostaną wycofane.
- BŁĄD_APLIKACJI_PODNIESIENIA (- , ) można użyć zamiast RAISE, aby zgłosić błąd z niestandardowym kodem i komunikatem. Kod błędu musi mieścić się w zakresie od -20000 do -20999.





