Plan wykładu PL/SQL PL/SQL - historia
Transkrypt
Plan wykładu PL/SQL PL/SQL - historia
Plan wykładu 2 Wprowadzenie do PL/SQL Bloki Podstawowe składowe języka Zmienne i stałe Kursory TWORZENIE APLIKACJI BAZODANOWYCH Wykład 2: Wprowadzenie do PL/SQL: bloki anonimowe, zmienne, kursory Małgorzata Krętowska Wydział Informatyki Politechnika Białostocka PL/SQL 3 PL/SQL - historia 4 PL/SQL (Procedural Language SQL) Proceduralne (a czasem obiektowe) rozszerzenie programistyczne języka SQL, stworzone, udostępnione przez Oracle i przeznaczone do obsługi narzędzi tej firmy Wywodzi się z języka ADA Jest chroniony prawami autorskimi, Jest językiem trzeciej generacji 3GL, PL/SQL 1.0 wprowadzono w 1991 roku, wersja była ograniczona i brakowało w niej wielu funkcji, wypuszczona z wersją serwera bazodanowego 6.0, Kolejna wersja 2.3 udostępniała obsługę procedur i funkcji składowanych, Wersja 8.0 – wprowadzenie modelu obiektoworelacyjnego, Wersje 8.1, 9.0, 9.2, 10.0 to kolejne udoskonalenia języka, Najnowsza wersja to 11.0 Bloki 5 Struktura bloku 6 Podstawowa jednostka w PL/SQL Program składa się przynajmniej z jednego bloku Bloki mogą być zagnieżdżone Bloki mogą być wykonywane tylko raz, bez zapisywania (bloki anonimowe) Bloki można zapisywać w bazie w celu ich późniejszego wykorzystania (bloki nazwane) Bloki obsługują wszystkie instrukcje DML, a także DDL [DECLARE ] deklaracje zmiennych, wyjątki BEGIN wyrażenia SQL i PL/SQL [EXCEPTION ] obsługa wyjątków END; [] – opcjonalnie Blok nie może być pusty. Sekcja deklaracji 7 Sekcja wykonawcza 8 Jest to sekcja opcjonalna Umieszczamy w niej zmienne i ich typy, stałe, kursory, wyjątki definiowane przez użytkownika, wszystko to do czego odwołujemy się w kolejnej sekcji bloku Możliwość dokonania inicjalizacji Przykład DECLARE v_zmienna NUMBER; Obowiązkowa Rozpoczyna się od słowa kluczowego BEGIN Musi posiadać co najmniej jedną instrukcję Może zawierać dowolną liczbę bloków PL/SQL, zagnieżdżonych Może zawierać polecenia SQL lub PL/SQL Sekcja wyjątków 9 Typy bloków 10 Bloki anonimowe Opcjonalna Rozpoczyna się od słowa kluczowego EXCEPTION Pozwala na przechwytywanie błędów, które wystąpiły w sekcji wykonawczej Bloki nazwane Funkcje Procedury Bloki anonimowe 11 Przykład 12 Nie posiadają nazwy i nie są przechowywane w bazie danych Można w nich wywoływać inne programy, ale ich nigdzie nie można wywołać Są kompilowane za każdym razem gdy program jest uruchamiany Struktura bloku anonimowego – jak wcześniej. SET SERVEROUTPUT ON; - na zewnątrz bloku anonimowego umożliwia wypisywanie komunikatów DBMS_OUTPUT.PUT_LINE (‘komunikat’); - wypisywanie komunikatu DBMS_OUTPUT.NEW_LINE; - przejście do nowej linii Uruchamianie bloku 13 Uruchamianie bloku 14 Oracle SQL Developer: Uruchamianie: Run Script (F5); Wyniki: Script Output Oracle SQL*Plus: Uruchamianie: znak „/” na końcu kodu Uruchamianie bloku 15 Podstawowe składowe języka 16 Identyfikatory Ograniczniki Literały Słowa zarezerwowane Komentarze Oracle SQL*Plus: Jeżeli kod bloku jest zapisany w pliku (ze znakiem „/” na końcu): Uruchamianie: start ścieżka dostępu do pliku @ ścieżka dostępu do pliku Identyfikatory 17 Ograniczniki 18 Służą do nazywania zmiennych, kursorów, funkcji, procedur, etc., Zasady tworzenia identyfikatorów: +,-,*,/ - operatory matematyczne >,<,<>,=,!= - operatory porównania --, /*, */ - komentarze <<, >> - etykiety % - atrybuty (TYPE, etc.) ’ – ogranicznik łańcuchów znaków ” – ogranicznik identyfikatorów := - przypisanie, inicjalizacja zmiennej || - łączenie łańcuchów znaków <30 znaków Rozpoczynają się literą Mogą zawierać znaki $,#,_ i cyfry (oprócz pierwszej pozycji), Nie mogą zawierać znaków przestankowych, odstępów i myślników, Nie mogą zawierać słów zarezerwowanych, Wyjątek to identyfikatory w cudzysłowach - można w nich stosować prawie wszystko. Literały 19 Deklaracja zmiennych i stałych 20 Wartości, które nie są reprezentowane przez identyfikatory, ani nie są wyliczane na podstawie innych wartości: Zmienne: identyfikator typ_danych [NOT NULL] [:=wart_pocz | DEFAULT wart_pocz]; Stałe: identyfikator CONSTANT typ_danych [:=wart_pocz | DEFAULT wart_pocz]; Znakowe: np. ’abc’ Liczbowe: 1, 2, 456 Logiczne: TRUE, FALSE Związane z datą ’23-12-2013’ DECLARE v_zmienna NUMBER(5); v_nr NUMBER(3) NOT NULL := 10; c_stala CONSTANT NUMBER(2) DEFAULT 13; v_sprawdz BOOLEAN NOT NULL := TRUE; Typy zmiennych 21 Typy znakowe 22 Typy skalarne – typ o pojedynczej wartości CHAR ([(max długość)] – domyślnie 1; typ danych o stałej długości, pojemność określamy w bajtach: maksymalnie 32 767 bajtów w PL/SQL (w SQL – 2000 bajtów) VARCHAR2 (max długość) - typ danych o zmiennej długości, maksymalnie 32 767 bajtów ( w SQL – 4000 bajtów) Znaki i łańcuchy znaków Liczby Typy logiczne Data i czas Typy złożone – typ złożony z kilku odrębnych wartości (np. rekord, kolekcja (tablice, listy) , instancja typu obiektowego) Wskaźniki – logiczny wskaźnik danej wartości lub kursora LOB – identyfikator typu wielkoobiektowego (ang. large object) Typy liczbowe i logiczne 23 Data i czas 24 NUMBER [(precyzja, skala)] – precyzja: wartości od 1 do 38, skala: -84 do 127, identyczny z typem NUMBER bazy danych Podtypy: REAL (63 cyfry), DOUBLE PRECISION (126 cyfr), FLOAT (126 cyfr) BINARY_DOUBLE, BINARY_FLOAT - od wersji Oracle 10g, typ zmiennoprzecinkowy o podwójnej (pojedynczej) precyzji PLS_INTEGER – zakres od -2 147 483 648 do 2 147 483 647. Potrzebuje mniej przestrzeni na dysku niż NUMBER; bardziej efektywne wyliczenia BOOLEAN – wartości TRUE, FALSE, NULL DATE – podstawowy typ daty i czasu; przechowuje rok, miesiąc, dzień, godzinę, minutę, sekundę TIMESTAMP [(precyzja)] – rozszerzenie typu DATE o ułamki sekund, w tym celu określa się precyzję 0-9, domyślnie 6 Przechowywanie okresów czasów: INTERVAL YEAR [(precyzja)] TO MONTH – w latach i miesiącach INTERVAL DAY [(precyzja_dni)] TO SECOND [(precyzja_ułamki_sekund)] – w dniach, minutach i sekundach Typy zakotwiczone 25 Instrukcje warunkowa 26 zmienna%TYPE tabela.kolumna%TYPE tabela%ROWTYPE IF warunek THEN instrukcja-1; END IF; v_imie VARCHAR2(15); v_moje_imie v_imie%TYPE; ksiazki_record t_ksiazka%ROWTYPE IF warunek-1 THEN instrukcja-1; ELSIF warunek-2 THEN instrukcja-2; ELSE instrukcja-3; END IF; Instrukcja warunkowa Instrukcja CASE v_cena t_ksiazka.cena%TYPE; 27 IF warunek THEN instrukcja-1; ELSE instrukcja-2; END IF; 28 ……... IF v_cena > 100 THEN RETURN (v_cena*1.1); ELSIF v_cena >= 50 THEN RETURN (v_cena*1.2); ELSE RETURN (v_cena*1.25); END IF; ………. Od wersji 9i, Alternatywa dla instrukcji warunkowych IF upraszczająca składnię CASE warunek WHEN kryterium1 THEN operacje1; WHEN kryterium2 THEN operacje2; … [ELSE operacje;] END CASE; Instrukcja CASE - przykład 29 CASE z wyszukiwaniem 30 DECLARE CASE [TRUE| FALSE] WHEN warunek1 THEN operacje1; WHEN warunek2 THEN operacje2; … [ELSE operacje;] END CASE; selector NUMBER := 0; BEGIN CASE selector WHEN 0 THEN dbms_output.put_line('Case 0!'); WHEN 1 THEN dbms_output.put_line('Case 1!'); ELSE dbms_output.put_line('No match!'); Domyślnie poszukuje warunku prawdziwego (TRUE) END CASE; END; / CASE z wyszukiwaniem - przykład 31 Pętla prosta 32 BEGIN CASE LOOP instrukcje; EXIT [WHEN warunek]; END LOOP; WHEN 1 = 2 THEN dbms_output.put_line('Case [1 = 2]'); WHEN 2 = 2 THEN dbms_output.put_line('Case [2 = 2]'); ELSE dbms_output.put_line('No match'); END CASE; END; / Wynik działania CASE Przykład 33 CONTINUE [WHEN] 34 DECLARE Od wersji 11g Dodatkowe sterowanie pętlą Działanie: natychmiast kończy aktualną iterację i przechodzi do pierwszego działania w pętli counter NUMBER; first BOOLEAN; BEGIN LOOP IF NVL(counter,1) >= 1 THEN IF NOT NVL(first,TRUE) THEN counter := counter + 1; ELSE counter := 1; first := FALSE; END IF; END IF; dbms_output.put_line('Iteration ['||counter||']'); EXIT WHEN NOT counter < 3; END LOOP; END; / CONTINUE 35 CONTINUE 36 DECLARE counter NUMBER; IF counter = 2 THEN CONTINUE; first BOOLEAN; ELSE dbms_output.put_line('Index ['||counter||'].'); BEGIN LOOP IF NVL(counter,1) >= 1 THEN IF NOT NVL(first,TRUE) THEN counter := counter + 1; ELSE counter := 1; first := FALSE; END IF; END IF; EXIT WHEN NOT counter < 3; IF counter = 2 THEN CONTINUE; ELSE dbms_output.put_line('Index ['||counter||'].'); END IF; END LOOP; END; CONTINUE WHEN counter = 2; dbms_output.put_line('Index ['||counter||'].'); Instrukcje FOR i WHILE 37 Instrukcja FOR - przykład 38 DECLARE v_licznik NUMBER(1) :=0; v_ostatni NUMBER(1); v_min NUMBER(1) := 1; v_max NUMBER(1) := 5; WHILE warunek LOOP instrukcje; END LOOP; FOR licznik IN [REVERSE] min..max LOOP instrukcje; END LOOP; BEGIN Nie trzeba deklarować zmiennej i FOR i IN v_min..v_max LOOP v_licznik := v_licznik + 1; v_ostatni := i; END LOOP; dbms_output.put_line(‘Ostatni indeks:’ || TO_CHAR(v_ostatni) || ‘. Liczba petli:’ || TO_CHAR(v_licznik)); END; Instrukcja NULL Polecenie SELECT INTO 39 40 DECLARE i NUMBER(2) :=0; BEGIN ……… IF i > 10 THEN dbms_output.put_line(‘i jest większe od 10’); ELSE NULL; END IF; END; / NULL – oznacza brak akcji SELECT lista_zmiennych INTO nazwa_zmiennej | nazwa_rekordu FROM tabela [ WHERE warunki]; SELECT INTO przekazuje wartości uzyskane z bazy (lista_zmiennych) do zmiennych występujących w klauzuli INTO Polenie musi zwrócić jeden wiersz SELECT INTO - przykład 41 Pojęcie kursora 42 DECLARE bonus Udostępnia dane zwrócone przez zapytanie Otwarcie kursora to pobranie części bieżących danych, co oznacza, że modyfikacje danych po jego otwarciu nie będą widoczne w zbiorze, który zwrócił kursor. Dwa typy kursorów NUMBER(8,2); BEGIN SELECT salary * 0.10 INTO bonus FROM employees WHERE employee_id = 100; DBMS_OUTPUT.PUT_LINE('bonus = ' || TO_CHAR(bonus)); Niejawne Jawne END; / Typy kursorów Atrybuty kursora SQL 43 44 Niejawne Deklarowane są dla wszystkich instrukcji DML oraz SELECT PL/SQL zarządza automatycznie kursorem niejawnym Parametry kursora: SQL%nazwa_parametru Jawne Deklarowane przez programistę Programista zarządza kursorem jawnym Parametry kursora: Nazwa_kursora%nazwa_p arametru Nazwa atrybuty Opis SQL%ROWCOUNT Liczba wierszy, których dotyczyła ostatnia instrukcja SQL SQL%FOUND Atrybut logiczny, który przyjmuje wartość TRUE, gdy ostatnia instrukcja dotyczyla jednego lub więcej wierszy SQL%NOTFOUND Atrybut logiczny, który przyjmuje wartość TRUE, gdy ostatnia instrukcja dotyczyła zerowej liczby wierszy SQL%ISOPEN Zawsze przyjmuje wartość FALSE ponieważ PL/SQL zamyka kursory natychmiast po ich wykonaniu Kursory niejawne - przykład 45 Kursory niejawne - przykład 46 DECLARE DECLARE v_usuniete VARCHAR2(30); n NUMBER; BEGIN BEGIN DELETE FROM t_z_ksiazka WHERE id_zamowienia = ∥ SELECT 1 INTO n FROM dual; dbms_output.put_line('Selected ['||SQL%ROWCOUNT||']'); END; ==================================================================== BEGIN v_usuniete := TO_CHAR(SQL%ROWCOUNT)|| ‘rekordow usunietych.’; END; UPDATE system_user SET last_update_date = SYSDATE; IF SQL%FOUND THEN dbms_output.put_line('Updated ['||SQL%ROWCOUNT||']'); ELSE dbms_output.put_line('Nothing updated!'); END IF; END; Kursory jawne 47 Sterowanie kursorami jawnymi 48 CURSOR nazwa_kursora [(parametr [, parametr] … )] IS instrukcja_select; NIE parametr ::= nazwa_parametru typ danych [{:= | DEFAULT wyrażenie}] DECLARE CURSOR kursor (p_isbn VARCHAR(10)) IS SELECT * FROM t_ksiazka WHERE isbn = p_isbn; OPEN FETCH PUSTY? TAK CLOSE Kursory jawne 49 Atrybuty kursora jawnego 50 Nazwa atrybuty Opis %ROWCOUNT Liczba wierszy, sprawdzonych w kursorze w danym momencie %FOUND Atrybut logiczny, który przyjmuje wartość TRUE, jeśli instrukcja FETCH zwróci wiersz %NOTFOUND Atrybut logiczny, który przyjmuje wartość TRUE, jeśli ostatnia instrukcja FETCH nie zwrócila żadnego wiersza %ISOPEN Atrybut logiczny, który przyjmuje wartość TRUE, jeśli kursor jest otwarty DECLARE ….. ; OPEN nazwa_kursora [(parametr [, parametr] ...)]; FETCH nazwa_kursora INTO zmienna [ , zmienna ...]; CLOSE nazwa_kursora; Kursor jawny - przykład 51 Pętla kursorowa FOR 52 DECLARE CURSOR k_cursor IS SELECT * FROM t_z_ksiazka WHERE isbn = 1; k_record t_z_ksiazka%ROWTYPE; v_ilosc t_z_ksiazka. ilosc %TYPE := 0; BEGIN OPEN k_cursor; LOOP FETCH k_cursor INTO k_record; IF k_cursor%NOTFOUND THEN EXIT; END IF; v_ilosc := v_ilosc + k_record.ilosc; END LOOP; dbms_output.put_line(k_cursor%ROWCOUNT); dbms_output.put_line(v_ilosc); CLOSE k_cursor; END; FOR nazwa_rekordu IN nazwa_kursora LOOP instrukcja-1; instrukcja-2; ……. END LOOP; Niejawne instrukcje OPEN, FETCH, CLOSE zmienna nazwa_rekordu – zadeklarowana niejawnie Pętla kursorowa FOR - przykład 53 Pętla kursorowa FOR- przykład 54 DECLARE CURSOR k_cursor (p_zam t_zamowienie.id_zamowienia%TYPE) IS SELECT * FROM t_z_ksiazka WHERE id_zamowienia = p_zam; DECLARE CURSOR a_cursor IS SELECT * FROM t_autor; ======== Metoda 1 ======================== BEGIN FOR i IN a_cursor LOOP dbms_output.put_line(i.nazwisko); END LOOP; END; ======== Metoda 2 ======================== BEGIN FOR i IN (SELECT * FROM t_autor) LOOP dbms_output.put_line(i.nazwisko); END LOOP; END; BEGIN FOR i IN k_cursor(1) LOOP dbms_output.put_line(i.isbn); END LOOP; END; Klauzula FOR UPDATE 55 Klauzula WHERE CURRENT OF 56 CURSOR nazwa_kursora [(parametr,… )] IS instrukcja_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 Gdy użyjemy NOWAIT, przy otwieraniu kursora program zostanie zamknięty, jeśli nie może utworzyć blokady na wyłączność. DECLARE CURSOR k_cursor(v_zakres ksiazka.cena%TYPE) IS SELECT cena FROM ksiazka WHERE cena > v_zakres FOR UPDATE; BEGIN FOR i IN k_cursor(40) LOOP UPDATE ksiazka SET cena = cena* 1.1 WHERE CURRENT OF k_cursor; END LOOP; COMMIT; END; Klauzula WHERE CURRENT OF 57 Literatura 58 Używając kursorów można aktualizować lub usuwać rekordy Klauzula FOR UPDATE blokuje wiersze Klauzula WHERE CURRENT OF odwołuje się do bieżącego rekordu z kursora jawnego Nie wolno zatwierdzać instrukcji z kursora jawnego, jeżeli użyta jest klauzula FOR UPDATE McLaughlin, Michael, Oracle Database 11g PL/SQL programming, Oracle Press, 2008 www.oracle.com