Plan wykładu Spis treści 1 Kursory 1 2 Wyjątki 4 2.1 Wyjątki predefiniowane............................. 4 2.2 Wyjątki niezdefiniowane wcześniej....................... 5 2.3 Definiowanie własnych wyjątków........................ 6 3 Podsumowanie 8 4 Źródła 8 1 Kursory Kursor Kursor - posiadający nazwę wskaźnik do prywatnej przestrzeni roboczej pozwalającej składować i udostępniać wynik zapytania SELECT albo zapytań DML manipulujących na danych (INSERT, UPDATE, DELETE albo MERGE). Rodzaje kursorów Kursory niejawne - tworzone automatycznie dla wszystkich zapytań SQL manipulujących na danych oraz dla zapytań SELECT wewnątrz PL/SQL. Kursory jawne - tworzone i zarządzanie przez programistę dla zapytań, które zwracają więcej niż jeden wiersz. Kursor jawny Obsługa kursora jawnego (instrukcje sterujące): deklaracja, otwarcie (OPEN), pobranie danych (FETCH), zamknięcie (CLOSE). Deklaracja kursora Deklaracja kursora: CURSOR nazwa [(parametr1 typ [:= DEFAULT wartosc1] [, parametr2])] [RETURN typ] IS SELECT; Przykłady: 1
CURSOR c_szefowie IS SELECT DISTINCT kierownik FROM pracownicy; CURSOR c_dzial (p_id NUMBER) IS CURSOR c_pracownicy RETURN pracownicy%rowtype; Otwarcie kursora OPEN nazwa (lista_parametrow); Np.: OPEN c_dzial(20); Pobranie danych FETCH nazwa INTO {lista_zmiennych zmienna_rekordowa}; Np.: vr_pracownik pracownicy%rowtype; OPEN c_dzial(20); FETCH c_dzial INTO v_pracownik; Zamknięcie kursora CLOSE nazwa; Np.: vr_pracownik pracownicy%rowtype; OPEN c_dzial(20); FETCH c_dzial INTO v_pracownik; CLOSE c_dzial; 2
Atrybuty kursora jawnego Każdy kursor posiada atrybuty: %ISOPEN - zwraca TRUE jeżeli kursor jest otwarty, w przeciwnym razie zwraca FALSE (dla niejawnego zawsze FALSE), %FOUND - po otwarciu kursora ale przed pierwszym pobraniem danych zwraca NULL; zwraca TRUE jeżeli ostatnie pobranie (FETCH) zwróciło dane albo FALSE jeśli nie zwróciło danych, %NOTFOUND - po otwarciu kursora ale przed pierwszym pobraniem danych zwraca NULL; zwraca TRUE jeżeli ostatnie pobranie nie zwróciło danych albo TRUE jeśli zwróciło dane, %ROWCOUNT - zwraca liczbę pobranych wierszy od momentu otwarcia kursora; przed pierwszym pobraniem zwraca 0. Pętle obsługujące kursor vr_pracownik pracownicy%rowtype; OPEN c_dzial(20); LOOP FETCH c_dzial INTO vr_pracownik; EXIT WHEN c_dzial%notfound OR c_dzial%notfound IS NULL; dbms_output.put_line(c_dzial%rowcount '. ' vr_pracownik.nazwisko); END LOOP; dbms_output.put_line('wybrano ' c_dzial%rowcount ' wierszy.'); CLOSE c_dzial; Pętla FOR obsługująca kursor I FOR vr_pracownik IN c_dzial(20) LOOP dbms_output.put_line(vr_pracownik.nazwisko); END LOOP; Pętla FOR obsługująca kursor II v_id pracownicy.id_dzialu%type := &id; FOR vr_pracownik IN (SELECT * FROM pracownicy WHERE id_dzialu = v_id ) LOOP dbms_output.put_line(vr_pracownik.nazwisko); END LOOP; 3
2 Wyjątki Wyjątki Wyjątek Czym jest wyjątek? Wyjątek błąd który może wystąpić w czasie wykonywania bloku PL/SQL. Zdarzenie to powoduje przerwanie normalnego toku działania programu. Wyjątek można obsłużyć wychwytując go (obsługa sytuacji wyjątkowej) albo przekazując go (propagacja) do środowiska uruchomienia programu. Wyjątek może być wywołany niejawnie przez serwer Oracle albo jawnie przez program. Rodzaje wyjątków Wywoływane niejawnie zdefiniowane wcześniej nie zdefiniowane wcześniej Wywoływane jawnie - predefiniowane przez użytkownika 2.1 Wyjątki predefiniowane Wyjątki predefiniowane Niektóre wyjątki zgłaszane automatycznie przez system: CASE_NOT_FOUND - żadna z podanych klazul WHEN nie spełnia warunku, a nie przewidziano sekcji domyślnej ELSE. CURSOR_ALREADY_OPEN - próba otwarcia otwartego kursora; kursor musi być zamknięty przed próbą ponownego otwarcia go. DUP_VAL_ON_INDEX - próba naruszenia ograniczenia unikalnej wartości. INVALID_CURSOR - nielegalna operacja na kursorze, np. próba zamknięcia nieotwartego kursora. INVALID_NUMBER - w wyrażeniach SQL błąd konwersji znaków na liczbę wartości (ciąg zanków nie przedstawia prawidłowej liczby). W kodzie PL/SQL wywoływany jest błąd VALUE_ERROR. LOGIN_DENIED - nieudana próba połączenia do bazy, błędny login albo hasło. NO_DATA_FOUND - instrukcja SELECT INTO nie zwróciła żadnego wiersza albo program odnosi się do usuniętego elementu w zagnieżdżonej tabeli albo do niezainicjowanego elementu w tabeli asocjacyjnej. NOT_LOGGED_ON - program próbuje operować na baze danych nie będąc z nią połączonym. TIMEOUT_ON_RESOURCE - przekroczenie czasu oczekiwania na zasoby przekazywane do bazy danych. TOO_MANY_ROWS - instrukcja SELECT INTO zwróciła więcej niż jeden wiersz. 4
VALUE_ERROR - wystąpił błąd arytmetyczny, konwersji, przycięcia wartości albo przekroczenia ograniczenia jej rozmiaru. ZERO_DIVIDE - próba dzielenia przez zero. Funkcje umożliwiające identyfikację błędu Identyfikacja błędu (obie funkcje bez parametrów): SQLERRM - funkcja zwraca opis błęduzwiązanego z wyjątkiem, który wystąpił jako ostatni. SQLCODE - funkcja zwracająca numer wyjątku, który wystąpił jako ostatni. Dla wyjątków wewnętrznych zwraca numer błędu z bazy Oracle. Wychwytywanie wyjątków WHEN wyjatek1 [OR wyjatek2 ] THEN instrukcje1; [WHEN wyjatek3 [OR wyjatek4 ] THEN instrukcje2; ] [WHEN OTHERS THEN instrukcje_n;] Sekcja WHEN OTHERS Sekcja OTHERS jest używana do obsługi wszystkich wyjątków, które nie zostały wcześniej określone. Sekcja OTHERS musi być ostatnia na liście obsługi wyjątków. 2.2 Wyjątki niezdefiniowane wcześniej Wyjątki niezdefiniowane wcześniej Są dowolnymi innymi standardowymi błędami serwera Oracle Muszą być zadeklarowane w sekcji deklaracji Należy powiązać podaną nazwę z zewnętrznym numerem błędu używając: PRAGMA _INIT Wyjątki niezdefiniowane wcześniej e_insert ; PRAGMA _INIT(e_insert, -014000); INSERT INTO dzial (id_dzialu, nazwa) VALUES(300, 'Executives') WHEN e_insert THEN DBMS_OUTPUT.PUT_LINE ('Błąd wstawiania'); / 5
2.3 Definiowanie własnych wyjątków Wyjątki użytkownika Jak tworzyć i obsługiwać własne wyjątki? Korzystanie z wyjątków użytkownika I deklaracja nazwa_wyjatku ; podniesienie wyjątku RAISE nazwa_wyjatku; przechwycenie w sekcji obsługi wyjątków. WHEN wyjatek1 THEN instrukcje1; WHEN wyjatek2 THEN instrukcje2; WHEN OTHERS THEN instrukcje_n; Korzystanie z wyjątków użytkownika II e_zla_wartosc ; RAISE e_zla_wartosc; WHEN e_zla_wartosc THEN dbms_output.put_line('bledna wartosc identyfikatora.'); 6
Propagacja wyjątków I RAISE e_zla_wartosc; WHEN e_zla_wartosc THEN dbms_output.put_line('bledna wartosc identyfikatora.'); Propagacja wyjątków II RAISE e_zla_wartosc; WHEN TOO_MANY_ROWS THEN dbms_output.put_line('za duzo wartosci.'); WHEN e_zla_wartosc THEN dbms_output.put_line('bledna wartosc ident'); Propagacja wyjątków III RAISE e_zla_wartosc; WHEN TOO_MANY_ROWS THEN dbms_output.put_line('za duzo wartosci.'); 7
WHEN VALUE_ERROR THEN dbms_output.put_line('blad konwersji.'); Raise application error Wywołania procedury Raise_application_error pozwala przerwać działanie programu i wyprowadzić na ekran informacje o błędzie. Pozwala to pominąć zwracanie niewychwyconego wyjątku. Składnia: Raise_application_error( numer_bledu, opis[, {TRUE FALSE}]); Numer błedu zawiera się w przedziale od -20000 do -20999, a opis może zajmować 2048 bajtów. Opcjonalny trzeci parametr dla wartości FALSE (domyślnie) powoduje, że zgłaszany błąd zastępuje wszystkie wcześniejsze błędy na stosie. Wartość TRUE oznacza dodanie błędu do stosu wcześniejszych błędów. Raise application error Przykład użycia: Raise_application_error(-20002, 'Błędny identyfikator'); ELSE 3 Podsumowanie Podsumowanie PL/SQL pozwala na: korzystanie ze zmiennych, stałych, korzystanie z instrukcji sterujących, przetwarzanie sekwencyjne zorientowane na dane, obsługiwanie wyjątków, użycie wcześniej zdefiniowanych pakietów i bibliotek, i wiele innych o czym na następnym wykładzie 4 Źródła Źródła http://docs.oracle.com/cd/b28359_01/appdev.111/b28370/toc.htm M. Lentner, Oracle 9i Kompletny podrêcznik u ytkownika, PJWSTK - W-wa, 2003 http://www.ploug.org.pl/showhtml.php?file=szkola/szkola_9/materialy 8
http://plsql-tutorial.com/index.htm http://www.toadworld.com/platforms/oracle/w/wiki/8243.plsql-obsession. aspx 9