CATEGORII DOCUMENTE |
Bulgara | Ceha slovaca | Croata | Engleza | Estona | Finlandeza | Franceza |
Germana | Italiana | Letona | Lituaniana | Maghiara | Olandeza | Poloneza |
Sarba | Slovena | Spaniola | Suedeza | Turca | Ucraineana |
DOCUMENTE SIMILARE |
|
Wyjątek definiuje się w sekcji deklaracji.
Składnia:
wyjątek EXCEPTION
Przykład
DECLARE
brak_prowizji EXCEPTION;
Wywołanie:
RAISE wyjątek;
Wywołanie wyjątku powoduje przekazanie sterowania do sekcji obsługi wyjątków i błędów i wykonanie instrukcji związanych z obsługą danego wyjątku. W sekcji obsługi wyjątków i błędów mosna równies usyć instrukcji RAISE. Spowoduje to przejście do sekcji obsługi wyjątków i błędów bloku zewnętrznego.
Obsługa
Sekcja obsługi wyjątków i błędów zawiera ciąg instrukcji o następującej składni:
WHEN wyjątek [ OR wyjątek ] THEN zestaw_instrukcji;
Aby wyjątek został obsłusony, musi istnieć odpowiadająca mu klauzula WHEN.
W przeciwnym przypadku blok PL/SQL'a zakończy się z błędem.
Co się dzieje po wywołaniu zadeklarowanego wyjątku?
Sterowanie przechodzi do sekcji obsługi wyjątków i błędów
Wykonywane są instrukcje z odpowiedniej klauzuli WHEN i następuje wyjście z bloku
Jeseli nie istnieje odpowiednia klauzula WHEN lub w ogóle nie ma sekcji obsługi wyjątków i błędów - następuje wyjście z bloku z błędem
Uwagi
Obsłusony mose być tylko jeden (pierwszy) wyjątek lub błąd.
Jeseli obsługa wyjątku lub błędu zakończy się z błędem, blok PL/SQL'a zakończy się właśnie z tym błędem.
Wyjątek A jest obsługiwany lokalnie, w bloku wewnętrznym. Sterowanie wraca bez błędu do bloku zewnętrznego |
|
Wyjątek B jest propagowany do bloku zewnętrznego z odpowiednia klauzula WHEN. Następnie sterowanie wraca do programu zewnętrznego bez błędu. |
|
Wyjątek C nie ma odpowiadającej mu klauzuli w bloku wewnętrznym ani w bloku zewnętrznym. Wykonanie bloku PL/SQL kończy się z błędem. |
|
Ćwiczenie 6.1
Oblicz dla danego sprzedawcy procent jaki stanowi prowizja w stosunku do jego całych dochodów. Jeseli zostanie podany pracownik nie będący sprzedawcą lub nie otrzymujący prowizji - obsłus to jako wyjątki. Propozycja:
set echo off
set termout on
set verify off
set feedback off
set pause off
accept Nazwisko prompt 'Podaj nazwisko sprzedawcy: '
declare
brak_prowizji exception;
inny_zawod exception;
pensja_ number;
prowizja_ number;
zawod_ varchar2(30);
begin
select sal,
comm,
job
into pensja_,
prowizja_,
zawod_
from emp
where ename = upper( '&Nazwisko');
if zawod_ != 'SALESMAN'
then
raise inny_zawod;
elsif nvl(prowizja_, 0) = 0
then
raise brak_prowizji;
else
insert into uwaga (komunikat)
values ( 'Pracownik uzyskał prowizję w wysokości '||
to_char(round(prowizja_/(pensja_+prowizja_),4)*100) ||
'% całych dochodów' );
end if;
exception
when inny_zawod
then
insert into uwaga (komunikat)
values ('Ten pracownik nie jest sprzedawcą');
when brak_prowizji
then
insert into uwaga (komunikat)
values ('Ten sprzedawca nie uzyskał prowizji');
end;
select * from uwaga;
delete from uwaga;
set verify on
set feedback on
set echo on
Deklaracja
Obsługa wyjątków mose obejmować równies obsługę błędów Oracle'a. W tym celu, w sekcji deklaracji nalesy usyć następującej instrukcji:
PRAGMA EXCEPTION_INIT ( wyjątek, kod_błędu )
Przykład
DECLARE
PRAGMA EXCEPTION_INIT ( za_duzo_cyfr, -1438);
Wywołanie
Wyjątek związany z błędem Oracle'a jest uruchamiany tylko przez wystąpienie tego błędu. Nie mose być wywołany poprzez RAISE.
Przykład
UPDATE emp SET deptno = 100 WHERE ename = 'SMITH';
Powyssze polecenie spowoduje błąd Oracle'a:
ORA-1438 Wartość większa nis dopuszczona przez wyspecyfikowaną dla tej kolumny precyzję
Jeseli taki błąd został zadeklarowany w sekcji deklaracji za pomocą instrukcji PRAGMA, to sterowanie przejdzie do sekcji obsługi wyjątków i błędów.
Obsługa
Błędy Oracle'a zadeklarowane instrukcją PRAGMA są obsługiwane jak wyjątki definiowane przez programistę.
Błędy predefiniowane
Istnieje cały szereg błędów Oracle'a posiadających swoje predefiniowane nazwy. Mosna je obsługiwać w sekcji obsługi wyjątków i błędów bez dodatkowych deklaracji.
CURSOR_ALREADY_OPEN |
próba otwarcia otwartego kursora |
|
DUP_VAL_ON_INDEX |
próba duplikacji kolumn chronionych indeksem unikalnym |
|
INVALID_CURSOR |
próba odwołania się do zamkniętego kursora |
|
INVALID_NUMBER |
nieudana konwersja tekstu na liczbę |
|
LOGON_DENIED |
nieudane podłączenie do bazy danych |
|
NO_DATA_FOUND |
brak danych |
|
NOT_LOGGED_ON |
brak podłączenia do bazy danych |
|
PROGRAM-ERROR |
błąd wewnętrzny PL./SQL'a |
|
STORAGE_ERROR |
przekroczenie lub uszkodzenie pamięci |
|
TIMEOUT_ON_RESOURCE |
zbyt długie oczekiwanie na zasoby |
|
TOO_MANY_ROWS |
SELECT INTO zwróciło więcej nis jeden wiersz |
|
VALUE_ERROR |
INSERT lub UPDATE próbuje wstawić niepoprawne dane |
|
ZERO_DIVIDE |
dzielenie przez zero |
|
OTHERS |
reprezentuje wszystkie, nie obsługiwane inaczej wyjątki; klauzula WHEN OTHERS musi być umieszczona na końcu sekcji |
Uwaga
Podane kody są kodami wyjątków PL/SQL'a. Odpowiadające im błędy Oracle'a mają kody dodatnie. Wyjątkiem jest NO_DATA_FOUND. Kod PL/SQL'a wynosi +100. Odpowiadajacy mu błąd Oracle'a ma kod ORA-01403.
Ćwiczenie 6.2
Oblicz dla danego sprzedawcy ile razy jego pensja jest wyssza od prowizji. Do wychwycenia zerowej prowizji lub innego błędu (np. błędnego nazwiska) posłus się wyjątkami predefiniowanymi. Propozycja:
set echo off
set termout on
set verify off
set feedback off
set pause off
accept Nazwisko prompt 'Podaj nazwisko sprzedawcy: '
declare
inny_zawod exception;
pensja_ number;
prowizja_ number;
zawod_ varchar2(30);
begin
select sal,
comm,
job
into pensja_,
prowizja_,
zawod_
from emp
where ename = upper( '&Nazwisko');
if zawod_ != 'SALESMAN'
then
raise inny_zawod;
end if;
insert into uwaga (komunikat)
values ( 'Pracownik otrzymuje pensję '||
to_char(round(pensja_/prowizja_,2)) ||
'-krotnie większą od prowizji');
exception
when inny_zawod
then
insert into uwaga (komunikat)
values ('Ten pracownik nie jest sprzedawcą');
when zero_divide
then
insert into uwaga (komunikat)
values ('Ten sprzedawca nie uzyskał prowizji');
when others
then
insert into uwaga (komunikat)
values ('Wystąpił nieprzewidziany błąd');
end;
select * from uwaga;
delete from uwaga;
set verify on
set feedback on
set echo on
SQLCODE
Zwraca kod aktualnego wyjątku
Jest usyteczna w sekcji obsługi wyjątków i błędów - poza nią zwraca zero
Dla wyjątku definiowanego przez programistę, niezwiązanego z błędem Oracle, zwraca +1
Nie mosna jej usywać w poleceniach SQL'a
SQLERRM
Zwraca komunikat związany z aktualnym wyjątkiem
Jest usyteczna w sekcji obsługi wyjątków i błędów - poza nią zwraca zawsze
ORA-0000: normal, succesfull completion
Dla wyjątku definiowanego przez programistę, niezwiązanego z błędem Oracle, zwraca
User-Defined Exception
Dla błędu Oracle'a zwraca odpowiedni komunikat
Nie mosna jej usywać w zdaniach SQL'a
SQLERRM (kod
Zwraca komunikat związany z podanym kodem
Nie mosna jej usywać w zdaniach SQL'a
Ćwiczenie 6.3
Oblicz dla danego sprzedawcy ile razy jego pensja jest wyssza od prowizji. Do wychwycenia zerowej prowizji lub innego błędu (np. błędnego nazwiska) posłus się klauzulą WHEN OTHERS wpisując w niej kod i komunikat błędu do tablic UWAGA. Propozycja:
set echo off
set termout on
set verify off
set feedback off
set pause off
accept Nazwisko prompt 'Podaj nazwisko sprzedawcy: '
declare
inny_zawod exception;
pensja_ number;
prowizja_ number;
zawod_ varchar2(30);
kod_bledu_ number;
tekst_bledu_ varchar2(80);
begin
select sal,
comm,
job
into pensja_,
prowizja_,
zawod_
from emp
where ename = upper( '&Nazwisko');
if zawod_ != 'SALESMAN'
then
raise inny_zawod;
end if;
insert into uwaga (komunikat)
values ( 'Pracownik otrzymuje pensję '||
to_char(round(pensja_/prowizja_,2)) ||
'-krotnie większą od prowizji');
exception
when inny_zawod
then
insert into uwaga (komunikat)
values ('Ten pracownik nie jest sprzedawcą');
when others
then
kod_bledu_ := SQLCODE;
tekst_bledu_ := SQLERRM;
insert into uwaga (komunikat)
values ('Wystąpił błąd. Kod błędu: '||
to_char(kod_bledu_) );
insert into uwaga (komunikat)
values ( tekst_bledu_ );
end;
select * from uwaga;
delete from uwaga;
set verify on
set feedback on
set echo on
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 664
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved