Plan wykładu Kursory: deklaracja, otwieranie, pobieranie danych, zamykanie Kursory: atrybuty Kursory: pętle, rekordy Kursory z parametrami BAZY DANYCH II WYKŁAD 4 dr inż. Agnieszka Bołtuć Co to jest kursor? Udostępnia podzbiór danych zdefiniowanych przez zapytanie, Dane pobierane są do pamięci i kursor jest do niej wskaźnikiem, Otwarcie kursora to pobranie części bieżących danych, co oznacza, że zmiana, dodanie lub usunięcie danych po jego otwarciu nie będzie miało odzwierciedlenia w zbiorze który zwrócił kursor. Rodzaje kursorów Bezpośrednie (Explicit) deklarowane i kontrolowane przez programistę, deklarowane w instrukcji SELECT (najczęściej takich, które zwracają więcej niż jeden wiersz) w części deklaracyjnej, Pośrednie (Implicit) kontrolowane przez PL/SQL, powstają przy każdym uruchomieniu poleceń z zakresu DML oraz instrukcji SELECT INTO, Zmienne kursorowe typ, który można powiązać z innymi zapytaniami w jednym bloku, Podzapytania kursorowe umieszczanie kursorów w instrukcjach języka SQL. 1
Przetwarzanie kursorów Deklaracja kursorów DEKLARACJA OTWIERANIE POBIERANIE DANYCH ZAMYKANIE Odbywa się w części deklaracyjnej, obejmuje nadanie nazwy oraz definicję zapytania SELECT, CURSOR nazwa IS zapytanie SELECT; gdzie nazwa to dowolny identyfikator PL/SQL, zaś zapytanie to dowolna instrukcja SELECT oczywiście bez klauzuli INTO. Deklaracja kursorów - przykłady CURSOR c_employees IS SELECT employee_id, last_name, salary FROM employees WHERE job_id= IT_PROG ; CURSOR c_employees_1 IS SELECT * FROM employees WHERE department_id=100; Otwieranie kursorów OPEN nazwa; Kursory otwiera się w sekcji wykonawczej lub wyjątków, Instrukcja ta związana jest z: alokacją pamięci, przetworzeniem zapytania, zapisaniem wierszy w obszarze kontekstu i przygotowaniem zbioru wynikowego, W danym momencie aktywny jest tylko jeden rekord, po otwarciu jest to pierwszy rekord, Kursor jest otwierany także wtedy, gdy zapytanie nie zwróci żadnego rekordu. 2
Otwieranie kursorów - przykłady CURSOR c_employees IS SELECT employee_id, last_name, salary FROM employees WHERE job_id= IT_PROG ; Pobieranie rekordów Zanim użyjemy rekordów musimy je pobrać z obszaru kontekstu do zmiennej, Służy do tego instrukcja FETCH, która operuje rekord po rekordzie, FETCH nazwa INTO zmienne rekord; gdzie nazwa to nazwa otwartego kursora, zaś zmienne to nazwy zmiennych odpowiadających typom kolumn zbioru wynikowego bądź nazwa rekordu. Pobieranie rekordów - przykłady Zamykanie kursorów FETCH c_employees INTO v_emp_id; FETCH c_employees INTO v_emp_id, v_last_name; v_emp employees%rowtype; FETCH c_employees INTO v_emp; CLOSE nazwa; Powoduje zamknięcie kursora i zwolnienie pamięci, Kursor może być otwarty ponownie, Wyjątek invalid cursor jest wywoływany kiedy chcemy zamknąć kursor, który nie jest otwarty, bądź gdy chcemy pobrać dane z kursora już zamkniętego. 3
Atrybuty kursorów %FOUND sprawdza czy instrukcja FETCH zwróciła rekordy, zwraca wartość logiczną TRUE jeśli tak lub FALSE jeśli nie, %ISOPEN sprawdza czy kursor jest już otwarty, jeśli TRUE to tak, jeśli FALSE to nie, %NOTFOUND działa odwrotnie do %FOUND, %ROWCOUNT sprawdza liczbę wierszy pobranych z kursora, Atrybuty - przykłady IF NOT c_employees%isopen THEN OPEN c_employees END IF; FETCH c_employees INTO v_1,v_2,v_3; EXIT WHEN c_employees%notfound; v_licznik:= c_employees%rowcount; Pętla prosta Pętla WHILE FETCH c_employees INTO v_1; EXIT WHEN c_employees%notfound; FETCH c_employees INTO v_1; WHILE c_employees%found FETCH c_employees INTO v_1; 4
Pobieranie danych z kursora do rekordu r_employees employees%rowtype; CURSOR c_employees IS SELECT * FROM employees; FETCH c_employees INTO r_employees; EXIT WHEN c_employees%notfound; Pętla FOR Nie wymagają jawnych instrukcji OPEN, FETCH, CLOSE, Za pełną obsługę kursora odpowiada PL/SQL, Pętla używa zmiennej, której nie trzeba deklarować w części deklaracyjnej, FOR zmienna_rekordowa IN kursor Instrukcje; FOR r_employees IN c_employees DBMS_OUTPUT.PUT_LINE(r_employees.last_ name r_employees.salary); 5
FOR z użyciem podzapytań Kursory z parametrami FOR r_employees IN (SELECT * FROM employees) DBMS_OUTPUT.PUT_LINE(r_employees.last_nam e r_employees.salary); CURSOR nazwa [(lista_parametrow)] IS zapytanie SELECT; [(nazwa_parametru typ, )] OPEN nazwa [(wartości_parametrów)]; Lista parametrów jest opcjonalna, Są to dowolne prawidłowe parametry używane do wykonania zapytania, Kursory z parametrami - przykład CURSOR c_employees (i_id NUMBER) IS SELECT * FROM employees WHERE employee_id>i_id; OPEN c_employees(10); Klauzula FOR UPDATE CURSOR nazwa [(lista_parametrów)] IS zapytanie SELECT [FOR UPDATE [OF (lista_kolumn) [NOWAIT]]; Służy do blokowania rekordów po otwarciu kursora, Rekordy są dostępne dla innych sesji, ale tylko w trybie do odczytu. 6
Klauzula FOR UPDATE Klauzula FOR UPDATE Co gwarantuje klauzula FOR UPDATE: Dane przeglądane w kursorze nie zostaną zablokowane przez żadną inną sesję, Dane są spójne z obszarem kontekstu, Gdy użyjemy NOWAIT, przy otwieraniu kursora program zostanie zamknięty, jeśli nie może zająć blokady na wyłączność. CURSOR c_employees (i_id NUMBER) IS SELECT * FROM employees WHERE employee_id>i_id FOR UPDATE salary NOWAIT; WYKORZYSTANA LITERATURA J. Price, Oracle Database 11g i SQL. Programowanie. Helion, 2009. S. Urman, R. Hardman, M. McLaughlin, Oracle Database 10g. Programowanie w języku PL/SQL. Helion, 2008. www.oracle.com 7