W przypadku bloków zagnieżdżonych, jeśli wystąpi błąd w najgłębiej osadzonym bloku, sprawdzana jest obsługa błędu w sekcji EXCEPTION danego bloku. Jeśli ten wyjątek będzie w nim obsługiwany, błąd nie zostanie przekazany do bloku wyższego poziomu i wyższe bloki będą zachowywać się tak, jakby ten wyjątek nie wystąpił. Jeśli jednak wyjątek nie będzie obsługiwany w bloku w którym wystąpił, zostanie przekazany blok wyżej celem sprawdzenia czy tam ten błąd jest obsługiwany. Będzie się tak działo do momentu kiedy obsługa danego błędu nie pojawi się w którymś z poziomów zagnieżdżenia.
Ćwiczenia
1. Stwórz procedurę wyświetlającą na konsoli wynik dzielenia 2 wartości podanych jako jej parametry. Obsłuż błędy które mogą się pojawić w trakcie działania programu. Do obsługi błędów stwórz oddzielną procedurę z parametrem.
2. Do procedury stworzonej w ćwiczeniu nr. 1 dodaj własny wyjątek informujący użytkownika o równości dzielnika i dzielnej. Dodaj obsługę takiego wystąpienia.
Ten temat omawiam na poniższych szkoleniach:
• Programowanie w PL/SQL
• Podstawy SQL i PL/SQL
Możesz w nich uczestniczyć, a jako czytelnik tego bloga otrzymasz 10% zniżki - poinformuj o tym fakcie konsultanta.
1.ZADANIE
OdpowiedzUsuńCREATE OR REPLACE PROCEDURE dzielenie(a IN number, b IN number)
IS
wynik number;
wynik2 number;
BEGIN
wynik = a/b;
wynik2 = b/a;
dbms_output.put_line(‘Wynikiem dzielenia a/b jest : ’||wynik);
dbms_output.put_line(‘Wynikiem dzielwnie b/a jest: ’||wynik2);
end;
CREATE OR REPLACE PROCEDURE sprawdzam(a IN number, b IN number)
IS
BEGIN
exception
when VALUE_ERROR then
dbms_output.put_line(‘Nie wolno dzielić wyrazów ani liter !!’);
when ZERO_DIVIDE then
dbms_output.put_line(‘Nie wolno dzielić przez „0” !!’);
end;
DECLARE
a number;
b number;
BEGIN
a = 20;
b = 10;
sprawdzam(a,b);
dzielenie(a,b);
end;
2.ZADANIE
CREATE OR REPLACE PROCEDURE moj_wyjatek(a IN number, b IN number)
IS
wyjatek_moj exception;
BEGIN
If a=b then raise wyjatek_moj;
end if;
exception
when wyjatek_moj then
dbms_output.put_line(‘a nie może się równać b’);
end;
DECLARE
a number;
b number;
BEGIN
a = 20;
b = 10;
sprawdzam(a,b);
moj_wyjatek(a,b);
dzielenie(a,b);
end;
Ten komentarz został usunięty przez autora.
OdpowiedzUsuńCzy w zad.1 nie powinno być :
OdpowiedzUsuńcreate or replace procedure dzielenie(
argument1 in number,
argument2 in number)
is
wynik number;
begin
wynik:=argument1/argument2;
dbms_output.put_line(wynik);
end;
create or replace procedure sprawdzam(a in number, b in number)
is
begin
dzielenie(a,b);
exception
when ZERO_DIVIDE then
dbms_output.put_line('Nie wolno dzielić przez 0!');
when VALUE_ERROR then
dbms_output.put_line('Nie wolno dzielić wyrazów ani liter !!');
end;
DECLARE
a number;
b number;
BEGIN
a:= 0;
b:= 0;
sprawdzam(a,b);
dzielenie(a,b);
end;
male bledy, ale mi nie dzialalo poprawnie
a zad. 2
Usuńcreate or replace procedure sprawdzam(a in number, b in number)
is
wyjatek_rownosc exception;
begin
if a=b then raise wyjatek_rownosc;
end if;
dzielenie(a,b);
exception
when wyjatek_rownosc then
dbms_output.put_line('obydwie liczby rowne sobie!');
when ZERO_DIVIDE then
dbms_output.put_line('Nie wolno dzielić przez 0!');
when VALUE_ERROR then
dbms_output.put_line('Nie wolno dzielić wyrazów ani liter !!');
end;
DECLARE
a number;
b number;
BEGIN
a:= 0;
b:= 0;
sprawdzam(a,b);
dzielenie(a,b);
end;
Jeżeli zadanie ma na celu sprawdzenie tego, co jest opisane powyżej na temat przekazywania wyjątków to proponuję takie rozwiązanie zadań (3 wersje sprawdzające) :
Usuńcreate or replace procedure excptn(dzielna IN number, dzielnik IN number)
is
wynik number;
jedynka exception;
begin
dbms_output.put_line('procerura 1');
if dzielna=dzielnik then
raise jedynka;
end if;
begin
wynik:=dzielna/dzielnik;
dbms_output.put_line('wynik:' || wynik);
exception
when zero_divide then
dbms_output.put_line('Podzieliles przez zero');
when Value_error then
dbms_output.put_line('Zle wartosci przypisane');
end;
exception
when jedynka then
dbms_output.put_line('wartosc wynosi jeden! (zew)');
end;
create or replace procedure excptn2(dzielna IN number, dzielnik IN number)
is
wynik number;
jedynka exception;
begin
dbms_output.put_line('procerura 2');
begin
if dzielna=dzielnik then
raise jedynka;
end if;
wynik:=dzielna/dzielnik;
dbms_output.put_line('wynik:' || wynik);
exception
when zero_divide then
dbms_output.put_line('Podzieliles przez zero');
when Value_error then
dbms_output.put_line('Zle wartosci przypisane');
when jedynka then
dbms_output.put_line('wartosc wynosi jeden! (wew)');
end;
exception
when jedynka then
dbms_output.put_line('wartosc wynosi jeden! (zew)');
end;
create or replace procedure excptn3(dzielna IN number, dzielnik IN number)
is
wynik number;
jedynka exception;
begin
dbms_output.put_line('procerura 3');
begin
if dzielna=dzielnik then
raise jedynka;
end if;
wynik:=dzielna/dzielnik;
dbms_output.put_line('wynik:' || wynik);
exception
when zero_divide then
dbms_output.put_line('Podzieliles przez zero');
when Value_error then
dbms_output.put_line('Zle wartosci przypisane');
when OTHERS then
dbms_output.put_line('The OTHERS are comming');
end;
exception
when jedynka then
dbms_output.put_line('wartosc wynosi jeden! (zew)');
end;
declare
a number;
b number;
begin
a:=2;
b:=2;
excptn(a,b);
excptn2(a,b);
excptn3(a,b);
end;
rozwiązanie:
OdpowiedzUsuńcreate or replace procedure dzielenie(
a in number,
b in number
)
is
wynik number;
wyjatek1 exception;
wyjatek2 exception;
begin
if b=0 then
raise wyjatek1;
elsif a=b then
raise wyjatek2;
end if;
wynik:=a/b;
dbms_output.put_line('wynik dzielenia '||a||':'||b||' to '||wynik);
exception
when wyjatek1 then
dbms_output.put_line('nie dziel przez zero');
when wyjatek2 then
dbms_output.put_line('wynik to jeden');
when Value_erro then
dbms_output.put_line('nie ');
end;
/* Dzialajace prawidlowo zadanie zad1 */
OdpowiedzUsuńcreate or replace procedure dzielenie( Aa number,B number)
is
W number;
begin
sprawdzam(Aa,B);
W := Aa/B;
dbms_output.put_line('Wynik dzielenia to: ' || W);
end;
create or replace procedure sprawdzam(a in number, b in number)
is
w number;
begin
w:= a/b;
exception
when ZERO_DIVIDE then
dbms_output.put_line('Nie wolno dzielic przez 0!');
when VALUE_ERROR then
dbms_output.put_line('Nie wolno dzielic wyrazów ani liter !!');
end;
exec dzielenie (20,0);
/* Dzialajace prawidlowo zadanie zad1 */
/* Dzialajace prawidlowo zadanie zad2 */
OdpowiedzUsuńcreate or replace procedure dzielenie( Aa number,B number)
is
W number;
wyjatek exception;
begin
if Aa = B then raise wyjatek;
end if;
sprawdzam(Aa,B);
W := Aa/B;
dbms_output.put_line('Wynik dzielenia to: ' || W);
exception when wyjatek then
dbms_output.put_line('A nie moze sie rownac B');
end;
exec dzielenie (20,0);
/* Dzialajace prawidlowo zadanie zad2 */