BD2_IO_K2
Transkrypt
BD2_IO_K2
Bazy danych 2 – Laboratorium 2 Język PL/SQL: • złożony język programowania, dzięki któremu mamy możliwość uzyskać dostęp do bazy danych Oracle z różnych środowisk; • jest to język zintegrowany z serwerem bazy danych, co ma wpływ na szybkość i wydajność jego przetwarzania; • cel zajęć, to zapoznanie z podstawami języka PL/SQL takimi, jak: ◦ bloki, ◦ zmienne, ◦ typy danych, ◦ wyrażenia i operatory, ◦ struktury sterujące, ◦ rekordy, ◦ styl programowania. Dlaczego język PL/SQL? • Strukturalny język zapytań (SQL) pozwala na uzyskanie dostępu i korzystanie z relacyjnej bazy danych. • SQL jest elastycznym i wydajnym językiem, pozwalającym na manipulowanie i przetwarzanie danych w relacyjnej bazie danych, np. ◦ create table A ( A number(2) primary key, B varchar2(20) default 'Ala', C date default sysdate, D char(3) NOT NULL check (D in ('TAK', 'NIE')) ); • ◦ insert into A(A,D) values (1, 'TAK'); ◦ select * from A where upper(B) like upper('%r%'); ◦ delete from A where A between 2 and 4; ◦ update A set B = B || 'owa' where D = 'NIE'; SQL to: ◦ język czwartej generacji, tzn. że opisuje żądane zadanie, a nie sposób jego wykonania; ◦ jest prosty i udostępnia mniejszą liczbę poleceń; ◦ izoluje również użytkownika od wewnętrznych struktur danych i algorytmów; 1 Bazy danych 2 – Laboratorium 2 • PL/SQL (Procedural Language SQL) łączy możliwości i elastyczność SQL z konstrukcjami proceduralnymi języka trzeciej generacji: ◦ zmienne i typy danych (predefiniowane i definiowane przez użytkownika); ◦ struktury sterowania, np. instrukcja I F – THEN - ELSE i pętle. ◦ procedury i funkcje; ◦ typy obiektów i metody. ORACLE 11 g • http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html • system jest zgodny z normą ANSI (American National Standard Institute) języka SQL (SQL99 lub SQL2); • norma SQL99 nie definiuje rozszerzeń języka trzeciej generacji udostępnionych przez PL/SQL, ale system ORACLE 9i i wyżej jest zgodny z większością właściwości wymaganych przez część CORE tego standardu. BLOK PL/SQL • Podstawowa jednostka programu PL/SQL. • Może być anonimowy (tworzone dynamicznie i wykonywane jednorazowo) i nazwane takie, jak: ◦ bloki oznaczone etykietą – to bloki anonimowe, którym przydzielono etykietę, więc są tworzone dynamicznie i wykonywane jednorazowo. Pozwala to na odwoływanie się do zmiennych tego bloku; ◦ podprogramy – procedury i funkcje, są składowane w bazie danych i wykonywane są jawnie przez odwołanie do nich; ◦ wyzwalacze – są to bloki PL/SQL skojarzone ze zdarzeniami zachodzącymi w bazie danych. Są składowane w bazie danej i mogą być wielokrotnie, niejawnie wywoływane. 2 Bazy danych 2 – Laboratorium 2 Ogólna struktura programu-bloku jest następująca: [DECLARE /* deklaracja zmiennych, stałych, kursorów, wyjątków w ramach bloku */ sekcja deklaracji] BEGIN sekcja instrukcji/wykonania [EXCEPTION sekcja obsługi wyjątków] END; Struktura programu PL/SQL umożliwia zagnieżdżanie bloków (ang. nested blocks). -- początek głównego bloku [DECLARE /* deklaracja zmiennych, stałych, kursorów, wyjątków w ramach głównego bloku */ sekcja deklaracji] BEGIN sekcja instrukcji -- początek podbloku [DECLARE /* deklaracja zmiennych, stałych, kursorów, wyjątków w ramach podbloku */ sekcja deklaracji] [BEGIN ...sekcja instrukcji [EXCEPTION ...sekcja obsługi wyjątków] END;] -- koniec podbloku [EXCEPTION ...sekcja obsługi wyjątków] EBD; -- koniec głównego bloku 3 Bazy danych 2 – Laboratorium 2 Zmienne, stałe, kursory i wyjątki są pewnymi obiektami programu. Każdy z obiektów zadeklarowany w bloku jest traktowany jako obiekt lokalny, tzn. nie jest dostępny w żadnym z jego bloków nadrzędnych. Jest natomiast dostępny we wszystkich blokach podrzędnych, tzn. jest on globalny dla wszystkich podbloków. Dostępność obiektu w innych blokach jest określana mianem tzw. zakresu obiektu. W tym samym bloku może istnieć tylko jeden obiekt o danej nazwie. Natomiast w bloku podrzędnym można zdefiniować obiekt o takiej samej nazwie, jaki istnieje w bloku nadrzędnym. W programie PL/SQL mogą również występować komentarze: -- - komentarz jedno-linijkowy; /*...*/ - komentarz wielo-linijkowy. Jednostki leksykalne: • małe i duże litery alfabetu: a..z i A..Z; • cyfry: 0-9; • znaki odstępu: tabulacja, spacja, znak nowego wiersza; • symbole matematyczne: +, -, *, /, <, >, =; • znaki interpunkcyjne: ( ) { } [ ] ? ! ~ ; : . ' '' @ # $ ^ & _ |. Identyfikatory: • MUSZĄ zaczynać się od litery, po której może wystąpić dowolna sekwencja znaków złożona z liter, cyfr, znaków dolara ($), znaków podkreślenia (_) i znaków # (i tylko takich!). • NIE MOGĄ być dłuższe niż 30 znaków. • Identyfikatory NIE MOGĄ brzmieć tak samo jak słowa zarezerwowane (np. DATE, BEGIN). • W języku PL/SQL duże i małe litery nie są rozróżniane. • Jeżeli w identyfikatorze mają być rozróżniane duże i małe litery, i ma on zwierać spacje lub słowa kluczowe, to identyfikator ujmujemy w cudzysłów. 4 Bazy danych 2 – Laboratorium 2 Ograniczniki To symbole, które mają szczególne znaczenie i są wykorzystywane do oddzielania identyfikatorów od siebie: Symbol Opis Symbol Opis + Operator dodawania - Operator odejmowania * Operator mnożenia / Operator dzielenia = Operator równości < Operator mniejszości > Operator większości ( Początkowy ogranicznik wyrażenia ) Końcowy ogranicznik wyrażenia ; Znak końca instrukcji % Wskaźnik atrybutu , Separator elementów . Wskaźnik składnika @ Wskaźnik łącza bazy danych ' Ogranicznik ciągu znaków '' Ogranicznik cytowanego ciągu znaków : Wskaźnik zmiennej związanej ** Operator potęgowania <> Operator nierówności != Operator nierówności (równoważny z <>) ~= Operator nierówności (równoważny z !=) ^= Operator nierówności (równoważny z ~=) <= Operator „mniejszy lub równy” >= Operator „większy lub równy” := Operator przypisania => Operator skojarzenia .. Operator zakresu || Operator konkatenacji ciągu znaków << Początkowy ogranicznik etykiety >> Końcowy ogranicznik etykiety -- Wskaźnik komentarza jednowierszowego /* Początkowy wskaźnik komentarza wielowierszowego */ Końcowy wskaźnik komentarza wielowierszowego <spacja> Znak spacji <tab> Znak tabulatora <cr> Znak powrotu do nowego wiersza Literały To wartość znakowa, numeryczna lub logiczna, która nie jest identyfikatorem. • Znakowe – bez konwersji mogą być przypisywane zmiennym typu CHAR i VARCHAR2, np. '12345', 'Ala', '100%', 'Sto lat temu', ' ' ' ', ' ' - pusty ciąg znaków identyczny z NULL. • Numeryczne – reprezentują wartości liczb całkowitych lub rzeczywistych, bez konwersji mogą być przypisywane zmiennym typu NUMBER, np.: 123, 7, -12, 0, -17.1, 23.0. • Logiczne: TRUE, FALSE lub NULL. 5 Bazy danych 2 – Laboratorium 2 Sekcja DECLARE – składnia. DECLARE nazwa_zmiennej typ_zmiennej [długość] [CONSTANT] [:= | DEFAULT wartość_domyślna] [NOT NULL]; UWAGA: Zmienna zadeklarowana, lecz nie zainicjowana posiada wartość NULL. Przykład 1 Deklarowanie zmiennych i stałych – przykłady. Poniższe trzy deklaracje są równoważne. licznik NUMBER(4); licznik NUMBER(4) := NULL; licznik NUMBER(4) DEFAULT NULL; Nadanie wartości zmiennym przez przypisanie. ilosc NUMBER(2) := 50; Można też tak: ilosc_2 NUMBER(2) DEFAULT 100; Literały (w tym daty) ujmujemy w apostrofy. imie VARCHAR2(25) DEFAULT 'Artur'; czy_instalowac CHAR(3) := 'TAK'; data_domyslna DATE := '01-01-2000'; Wartość domyślna SYSDATE zwraca bieżącą datę oraz czas systemowy z dokładnością do jednej sekundy data_zatr DATE DEFAULT SYSDATE NOT NULL; Typ logiczny. Uwaga: język SQL nie posiada takiego typu. flaga BOOLEAN := FALSE; Stałe. Poniżej zadeklarowanych stałych NIE MOŻNA zmieniać w programie. Jest to wygodny sposób na unikanie prostych błędów. 6 Bazy danych 2 – Laboratorium 2 grudzien CONSTANT NUMBER(2) := 31; uczelnia CONSTANT VARCHAR2(100) := 'EWSIE'; drobinka CONSTANT NUMBER := 0.000001; Typy danych. Uwaga: typy danych w PL/SQL nie odpowiadają dokładnie analogicznym typom w SQL. NUMERYCZNE NUMBER [ ( p [ ,s] ) ] p maksymalnie o wartości 38, s wartość z przedziału -84 do 127. Ujemna wartość s oznacza zaokrąglenie wartości do określonej liczby miejsc z lewej strony kropki dziesiętnej. -- przykłady: NUMBER, NUMBER(10), NUMBER(10,3) DEC, DECIMAL, DOUBLE PRECISION, FLOAT, NUMERIC, REAL. BINARY_INTEGER od -2147483647 do 2147483647 NATURA od 0 do 2147483647 NATURALN od 0 do 2147483647 NOT NULL POSITIVE od 1 do 2147483647 POSITIVEN od 1 do 2147483647 NOT NULL SIGNTYPE od -1, 0, 1 PLS_INTEGER od -2147483647 do 2147483647 -- Wydajniejsza niż INTEGER i NUMBER, ZNAKOWE VARCHAR2 (L [CHAR | BYTE]) od 1 do 32767 bajtów -- Domyślnie CHAR -- Uwaga: w tabelach ten typ może mieć maksymalnie 4000 bajtów. VARCHAR (L) -- Nie zaleca się stosować. Używać raczej VARCHAR2. CHAR (L [CHAR | BYTE]) od 1 do 32767 bajtów -- Typ o stałej długości. Niedobór uzupełniany spacjami. NCHAR, NVCHAR2 7 Bazy danych 2 – Laboratorium 2 -- narodowy zestaw znaków DATE (wiek, rok, miesiąc, dzień, godzina, minuta, sekunda) 7 bajtów -- Data i godzina, dokładność do 1 sek. TIMESTAMP [(P)] (rok, miesiąc, dzień, godzina, minuta, sekunda) -- P dokładność pola sekundy (wartością domyślną jest 6) INTERVAL YEAR [(P)] TO MONTH przechowuje dane o odcinku czasu pomiędzy dwoma punktami; liczbę lat i miesięcy -- P liczba cyfr pola roku (wartością domyślną jest 2) INTERVAL DAY [(DP)] TO SECOND[(SP)] liczbę dni i sekund -- DP liczba cyfr pola dnia (wartością domyślną jest 2) -- SP liczba cyfr pola sekund (wartością domyślną jest 6) ROWID przechowuje identyfikator wiersza rowid – unikalny klucz każdego wiersza bazy danych. Wartości binarne o stałej długości zależnej od systemu operacyjnego. UROWID logiczne lub binarne identyfikatory wierszy. BOOLEAN -- Może przyjmować wartości: TRUE, FALSE, NULL. RECORD TABLE VARRAYS REF CURSOR BFILE LOB BLOB CLOB NCLOB 8 Bazy danych 2 – Laboratorium 2 Przykład 2 Program "nic nie robiący". BEGIN null; END; Przykład 3 Program "Hello, world". BEGIN DBMS_OUTPUT.PUT_LINE('Hello, world'); END; Aby zobaczyć wynik na ekranie należy ustawić wartość zmiennej SET SERVEROUTPUT na ON Przy wpisywaniu dłuższych programów wygodniej jest ich kod zapisywać do pliku tekstowego i uruchamiać wydając polecenie START lub @ (jak poniżej). Oba polecenia są prawie równoważne sobie (szczegóły patrz dokumentacja do programu SQL*Plus). SQL> @c:\temp\p1.txt SQL> START c:\temp\p1.txt UWAGA: Jeśli pojawi się komunikat „Input truncated to 1 characters”, można się go pozbyć dodając na końcu jedną pustą linię (po znaku ukośnika). Wpisanie znaku ukośnika powoduje wykonanie ostatniego bloku PL/SQL, który jest przechowywany w buforze. SQL> / Hello, world PL/SQL procedure successfully completed. SQL> 9 Bazy danych 2 – Laboratorium 2 Polecenie run działa podobnie do / (ukośnik), z tą różnicą, że wykonywane polecenie jest listowane. SQL> RUN 1 BEGIN 2 DBMS_OUTPUT.PUT_LINE('Hello, world'); 3* END; Hello, world PL/SQL procedure successfully completed. Polecenie execute pozwala wykonać pojedyncze polecenie PL/SQL. Pełną nazwę polecenia można skrócić do EXEC. SQL> EXECUTE DBMS_OUTPUT.PUT_LINE('Hello, world'); Hello, world PL/SQL procedure successfully completed. Trzeba uważać, na zmienną LINESIZE (bo mogą pojawić się mylące wyniki). SQL> SET LINESIZE 5 SQL> EXECUTE DBMS_OUTPUT.PUT_LINE('HHHHeeeellllllo') HHHHe eeell llllo PL/SQL procedure successfully completed. Polecenie LIST przytacza zawartość bufora. Wydane z parametrem lub parametrami wyświetla tylko wskazaną linię lub zakres linii. Gwiazdka wskazuje linię bieżącą. SQL> LIST 1 BEGIN 2 DBMS_OUTPUT.PUT_LINE('HHHHeeeellllllo'); 3* END; SQL> SQL> LIST 2 2* DBMS_OUTPUT.PUT_LINE('Hello, world'); SQL> LIST 1 1* BEGIN 10 Bazy danych 2 – Laboratorium 2 SQL> SQL> LSIT 2 3 2 DBMS_OUTPUT.PUT_LINE('Hello, world'); 3* END; Kod programu zawiera błąd składniowy (usunięto średnik kończący polecenie w drugiej linii). SQL> @'e:\p1.txt' END; * ERROR at line 3: ORA-06550: line 3, column 1: PLS-00103: Encountered the symbol "END" when expecting one of the following: := . ( % ; The symbol ";" was substituted for "END" to continue. ZMIENNE TYPU ZŁOŻONEGO: – zmienna typu rekordowego składa się z wielu zmiennych elementarnych, zwanych polami. Deklarujemy ją na dwa sposoby: – przy użyciu pseudoatrubutu %ROWTYPE – umożliwia deklarowanie zmiennych typu rekordowego, których struktura jest zgodna ze strukturą wiersza tabeli lub wiersza wyznaczonego przez tzw. kursor. pracownik_rekord pracownik%ROWTYPE; pracownik_rekord jest zmienną o strukturze odpowiadającej strukturze tabeli pracownik. Innymi słowy zmienna rekordowa składa się z pól odpowiadających kolumnom tabeli pracownik. Możemy odwołać się do dowolnego pola tej zmiennej poprzez użycie '.': pracownik_rekord.nazwisko; – przy użyciu złożonego typu danych RECORD – umożliwia deklarowanie zmiennej o dowolnej strukturze. Najpierw musimy zadeklarować typ rekordowy, by deklarować zmienne tego typu. – 11 Bazy danych 2 – Laboratorium 2 DECLARE TYPE pracownik_rekord1 IS RECORD ( nazwisko pracownik.nazwisko%TYPE, pensja number(6,2) not null :=900 ); gdzie %TYPE oznacza pseudoatrybut określający typ zmiennej zgodny z typem kolumny nazwisko w tabeli pracownik. pracownik1 pracownik_rekord1; - typ tablicowy – struktura dwukolumnowej macierzy, w której pierwsza kolumna jest wykorzystywana do indeksowania wierszy tablicy i musi być typu binary_integer; druga kolumna może być zadeklarowana z wykorzystaniem jednego z predefiniowanych typów prostych, np. char, number, date. Liczba wierszy tablicy jest praktycznie nieograniczona. DECLARE TYPE nazwa_typu_tablicowego IS TABLE OF typ_kolumny [NOT NULL] INDEX BY binary_integer; zmienna_tablicowa nazwa_typu_tablicowego; zmienna_tablicowa(numer_komórki); --wartość znajdująca się w tablicy na pozycji numer_komórki Przykład.4 declare type tablica is table of number index by binary_integer; tab_liczb tablica; begin tab_liczb(0) := 2; -- odwołanie do 0 elementu tablicy dbms_output.put_line(tab_liczb(0)); tab_liczb(1) := 2 * tab_liczb(0); dbms_output.put_line(tab_liczb(1)); tab_liczb(2) := 3*tab_liczb(1)-tab_liczb(0); dbms_output.put_line(tab_liczb(2)); end; / 12 Bazy danych 2 – Laboratorium 2 INSTRUKCJE STERUJĄCE – instrukcja warunkowa IF warunek1 THEN instrukcje; ELSIF warunek2 THEN instrukcje; ELSE instrukcje; END IF; warunek ma składnię: zmienna operator wartość Operator: >,<,=,!=, <=,>=, and, or, not, is null, like, between...and..., in, is not null, not like, not between... and..., not in. Wartość warunku: true, false, null. Przykład.5 DECLARE i NUMBER := 3; BEGIN IF i > 2 THEN DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wieksza od 2’); ELSIF i < 2 THEN DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej mniejsza od 2’); ELSE DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wynosi: ‘||i); END IF; END; / – instrukcja case CASE zmienna WHEN wartosc THEN instrukcje; ... ELSE instrukcje; END CASE; 13 Bazy danych 2 – Laboratorium 2 Jeśli chcemy wprowadzić wartość z klawiatury (interaktywnie) musimy użyć w tym celu deklaracji zmiennej lokalnej z użyciem &, a następnie wykorzystać wprowadzoną wartość do podstawienia pod zmienną w bloku. Przykład 6 DECLARE grade CHAR(1); BEGIN grade := '&grade'; CASE grade WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END; / – pętla podstawowa LOOP INSTRUKCJE; EXIT WHEN warunek; -–wyjście z pętli IF warunek THEN exit; END LOOP; Wyjście z pętli możliwe jest również poprzez użycie poleceń: goto lub raise. – pętla while WHILE warunek LOOP instrukcje; -- dopóki spełniony warunek -- wykonuj polecenia-instrukcje END LOOP; 14 Bazy danych 2 – Laboratorium 2 – pętla numeryczna for FOR zmienna_licznikowa IN x..y LOOP instrukcje; END LOOP; Polecenia pętli wykonywane są y razy. Przed pierwszą iteracją zmienna_licznikowa przyjmuje wartość x. Po kolejnych iteracjach pętli wartość zmiennej_licznikowej jest zwiększana o 1 (domyślnie). Polecenia wykonywane są dopóki wartość tej zmiennej jest mniejsza równa y. Klauzula reverse odwraca kierunek iteracji. Przykład 7 BEGIN - - Zmienna iteracyjna NIE MUSI być wcześniej deklarowana ani inicjowana. FOR i IN 1..5 LOOP DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wynosi: ‘||TO_CHAR(i)); END LOOP; - - Uwaga na słowo kluczowe REVERSE. Odwraca ono kierunek iteracji. FOR i IN REVERSE 1..5 LOOP DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wynosi: ‘||TO_CHAR(i)); END LOOP; - - Do wcześniejszego wyjścia z pętli można użyć polecenia EXIT FOR i IN 1..5 LOOP DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wynosi: ‘||TO_CHAR(i)); EXIT WHEN i = 3; END LOOP; - - Pętla nie wykona się ani razu. FOR i IN 6..5 LOOP DBMS_OUTPUT.PUT_LINE(‘Wartosc zmiennej wynosi: ‘||TO_CHAR(i)); END LOOP; END; / Z pętlami można wiązać etykiety, umożliwiające ich identyfikację, opuszczanie i testowanie wartości zawartych w nich zmiennych iteracyjnych. 15 Bazy danych 2 – Laboratorium 2 Przykład 8 BEGIN <<petla1>> -- etykieta pętli for i in 1..10 loop <<petla2>> for j in 1..20 loop if petla1.i > 5 then dbms_output.put_line('i: '||i); else dbms_output.put_line('j: '||j); end if; exit petla1 when i=7; end loop petla2; end loop petla2; END; / INSTRUKCJA SKOKU – zmienia kolejność wykonywania instrukcji oraz pozwala opuścić pętle. GOTO <etykieta> Przykład 9 DECLARE tekst VARCHAR2(100); BEGIN -- Etykieta musi poprzedzać polecenie wykonywane. GOTO nie może przeskakiwać -- warunkowych części poleceń. IF-THEN-ELSE, do polecenia LOOP i do bloku podrzędnego. <<pierwszy>> tekst := 'Ala '; GOTO drugi; <<wyswietl>> DBMS_OUTPUT.PUT_LINE(tekst); GOTO koniec; <<drugi>> tekst := tekst||'ma '; GOTO trzeci; <<trzeci>> tekst := tekst||'kota.'; GOTO wyswietl; <<koniec>> NULL; -- Polecenie NULL nie wykonuje żadnej akcji. END; / 16 Bazy danych 2 – Laboratorium 2 Przykład 10 BEGIN for i in 1..&n loop dbms_output.put_line(i); end loop; END; / Przykład 11 DECLARE n integer; BEGIN n:=&n; for i in 1..n loop dbms_output.put_line(i); end loop; END; / Przykład 12 DECLARE tekst varchar(20); BEGIN tekst:=&tekst; -- Wprowadzany tekst z klawiatury musi być ujęty w -- apostrofy ''. Inne rozwiązanie to: tekst:='&tekst'; -- Również zapis daty wymaga apostrofów. for i in 1..4 loop dbms_output.put_line(tekst ||' ' || i); end loop; END; / 17