sobota, 20 listopada 2010

Kurs Oracle PL/SQL. Propagacja wyjątków


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.

8 komentarzy:

  1. 1.ZADANIE
    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;

    OdpowiedzUsuń
  2. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń
  3. Czy w zad.1 nie powinno być :

    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

    OdpowiedzUsuń
    Odpowiedzi
    1. a zad. 2

      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;

      Usuń
    2. 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) :

      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;

      Usuń
  4. rozwiązanie:
    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;

    OdpowiedzUsuń
  5. /* Dzialajace prawidlowo zadanie zad1 */
    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 */

    OdpowiedzUsuń
  6. /* Dzialajace prawidlowo zadanie zad2 */
    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 */

    OdpowiedzUsuń