Język PL/SQL PL/SQL to specjalny język proceduralny stosowany w bazach danych Oracle. Język ten stanowi rozszerzenie SQL o szereg instrukcji, znanych w proceduralnych językach programowania. Umożliwia pisanie bloków programów, funkcji, procedur,... Możliwości, jakie daje język PL/SQL to: korzystanie z pętli oraz instrukcji warunkowych; dostęp do danych w plikach; poprawienie wydajności bazy danych; tworzenie rozbudowanych programów, do wykonania zadań niemożliwych do zrealizowania za pomocą samego SQL-a; obsługa błędów i wyjatków. W języku PL/SQL można tworzyć cztery rodzaje programów: 1. bloki anonimowe; 2. procedury składowane; 3. wyzwalacze; 4. funkcje. Bloki anonimowe w PL/SQL W języku PL/SQL można tworzyć bloki anonimowe, nie posiadające nazwy. Nie są zapisywane w bazie danych. Można ich używać w celu jednorazowego wykonania kodu. deklaracje zmiennych kod wykonywalny W poniższym przykładzie każdemu pracownikowi w tabeli employee dajemy podwyżkę o 100$. kwota NUMBER(4); kwota:=100; UPDATE employee SET salary=salary+kwota; Deklaracje zmiennych i stałych Zmienne i stałe deklarujemy w sekcji bloku anonimowego. Deklaracja zmiennej ma postać: zmienna typ_danych; Deklaracja stałej: stala1 CONSTANT typ_danych := wartość; Przykładowa sekcja deklaracji: liczba1 NUMBER(4); liczba2 INT :=90; liczba3 INT NOT NULL :=0; tekst1 VARCHAR2(30); data1 DATE default SYSDATE; stala1 CONSTANT CHAR(5) := tekst ; Użycie w deklaracji zmiennej instrukcji:=wyrażenie umożliwia inicjalizację wartości zmiennej w przeciwnym razie zmiennej jest przypisywane NULL. Do inicjalizacji wartości zmiennej zamiast operatora := można użyć klauzuli DEFAULT. Polecenia SQL w programach PL/SQL W kodzie programu PL/SQL można używać instrukcji INSERT, UPDATE, DELETE podobnie, jak w języku SQL. Instrukcji SELECT używamy łacznie z klauzulą INTO.
Polecenia SQL w programach PL/SQL W kodzie programu PL/SQL można używać instrukcji INSERT, UPDATE, DELETE podobnie, jak w języku SQL. Instrukcji SELECT używamy łacznie z klauzulą INTO. Przykład: użycie UPDATE w bloku anonimowym: kwota NUMBER(5):=200; dzial INT; dzial:=90; UPDATE employees SET salary=salary+kwota WHERE department_id=dzial; Polecenia SQL w programach PL/SQL W kodzie programu PL/SQL można używać instrukcji INSERT, UPDATE, DELETE podobnie, jak w języku SQL. Instrukcji SELECT używamy łacznie z klauzulą INTO. Przykład: użycie INSERT w bloku anonimowym: id char(2); nazwa varchar2(40); region number:=1; nazwa:= Poland ; id:= PL ; INSERT INTO countries(country_id,country_name,region_id) VALUES ( id,nazwa,region); Instrukcji DELETE używa się analogicznie. W przypadku SELECT musimy zastosować klauzulę INTO. Zapytanie SELECT w tym przypadku musi zwracać zawsze tylko jeden wiersz. W klauzuli INTO podajemy listę zmiennych, do których przypisywane są wartości z kolejnych pól zwracanych przez SELECT. Liczba i typy zmiennych muszą odpowiadać liczbie i typom wyrażeń zwracanych przez SELECT. W przypadku SELECT musimy zastosować klauzulę INTO. Zapytanie SELECT w tym przypadku musi zwracać zawsze tylko jeden wiersz. W klauzuli INTO podajemy listę zmiennych, do których przypisywane są wartości z kolejnych pól zwracanych przez SELECT. Liczba i typy zmiennych muszą odpowiadać liczbie i typom wyrażeń zwracanych przez SELECT. declare suma numeric(10); srednia numeric(10,2); begin select sum(salary),avg(salary) into suma, srednia from employees; DBMS_OUTPUT.put_line( suma: suma srednia: srednia); end;
W przypadku SELECT musimy zastosować klauzulę INTO. Zapytanie SELECT w tym przypadku musi zwracać zawsze tylko jeden wiersz. W klauzuli INTO podajemy listę zmiennych, do których przypisywane są wartości z kolejnych pól zwracanych przez SELECT. Liczba i typy zmiennych muszą odpowiadać liczbie i typom wyrażeń zwracanych przez SELECT. declare suma numeric(10); srednia numeric(10,2); begin select sum(salary),avg(salary) into suma, srednia from employees; DBMS_OUTPUT.put_line( suma: suma srednia: srednia); end; Przy testowaniu i uruchamianiu aplikacji składających się z kodu PL/SQL wygodnie jest pobierać dane do testowania z klawiatury i wypisywać informacje o przebiegu obliczeń na ekran. Realizuje się to za pomocą instrukcji: DBMS_OUTPUT.Put_line(napis); Instrukcje sterujace języka PL/SQL Instrukcja przypisania := zmienna :=wyrażenie; np. kwota:=100; akt_data:=sysdate; Instrukcje warunkowe Instrukcja warunkowaif...then...end IF. Składnia instrukcji IF: IF warunek THEN instrukcje; ELSIF warunek THEN instrukcje; ELSE instrukcje END IF; Jeżeli warunek podany w wyrażeniu IF jest spełniony, wykonywany jest blok instrukcji występujący za THEN. W przeciwnym przypadku i gdy spełniony jest warunek wyrażenia ELSIF, wykonywany jest blok instrukcji występujący po tym wyrażeniu. Jeżeli ten warunek nie jest spełniony, wykonywane są instrukcje z bloku ELSE. Uwaga. Użycie klauzul ELSIF oraz ELSE nie jest wymagane. Przykład: Chcemy policzyc pierwiastek równania ax+b=0. a number; b number; a:=1; b:=10; IF(a=0) then IF(b<>0) then dbms_output.put_line( brak rozwiązań ); ELSE dbms_output.put_line( nieskończenie wiele rozwiązań ); END IF; ELSE dbms_output.put_line( wynik: x= -b/a); END IF;
Instrukcja warunkowa CASE Instrukcja CASE występuje w dwóch formach. Użycie CASE z wyszukiwaniem, jak poniżej powoduje, że sprawdzane są kolejno warunki w klauzulach WHEN, do momentu natrafienia na taki, który będzie spełniony. Wykonywany będzie wówczas odpowiedni blok instrukcji. Pozostałe warunki nie są sprawdzane. Jeżeli żaden warunek nie jest spełniony, wykonywane są instrukcje z klauzuli ELSE (o ile taka klauzula istnieje). CASE WHEN warunek1 THEN instrukcje1; WHEN warunek2 THEN instrukcje2;... ELSE instrukcje; END CASE; Użycie CASE: i NUMBER(1) := 3; CASE WHEN i=1 THEN DBMS_OUTPUT.PUT_LINE( i wynosi 1 ); WHEN i>2 THEN DBMS_OUTPUT.PUT_LINE( i jest większe od 2 ); ELSE DBMS_OUTPUT.PUT_LINE( i wynosi i); END CASE; Instrukcja warunkowa CASE Druga forma instrukcji CASE sprawdza, czy wartość danego wyrażenia (zwanego selektorem) jest równa jednemu z wymienionych wyrażeń. Jeżeli tak, to wykonywane są odpowiednie instrukcje. Jeżeli wartość wyrażenia nie zostanie dopasowana, wykonywana jest klauzula ELSE (o ile występuje). CASE selektor WHEN wyrażenie1 THEN instrukcje1; WHEN wyrażenie2 THEN instrukcje2;... ELSE instrukcje; END CASE; Pętle. Pętla LOOP Pętle LOOP jest definiowana przy użyciu klauzul LOOP i END LOOP. Aby zakończyć działanie pętli LOOP, musimy podać warunek wyjścia: albo korzystając z klauzuli EXIT WHEN albo stosując instrukcję IF z klauzulą EXIT. Przykład pętli LOOP: i INT; i:=1; LOOP dbms_output.put_line( i= TO_CHAR(i)); EXIT WHEN i=10; i:=i+1; END LOOP;
Pętla WHILE Pętla FOR Pętli WHILE używamy aby instrukcja (lub blok instrukcji) była wykonywana, dopóki spełniony jest warunek pętli. WHILE warunek LOOP instrukcje END LOOP Definiując warunek w pętli WHILE należy pamiętać, że pętla będzie wykonywana tak długo, jak długo warunek określony w pętli będzie spełniony. Aby uniknąć pętli nieskończonej, należy umieścić w ciele pętli kod odpowiedzialny za zmianę tego warunku na fałszywy. Uwaga. Działanie pętli WHILE można również przerwać, stosując klauzulę EXIT WHEN. Pętli FOR używamy, gdy znamy liczbę iteracji. FOR iterator IN 1..n LOOP instrukcje END LOOP Zmienna iterator użyta do zdefiniowania pętli FOR nie jest deklarowana. Jej zasięg ogranicza się tylko do pętli. Nie można się do niej odnosić poza blokiem pętli. Domyślnie podaje się najpierw mniejszą, a potem większą z wartości zakresu iteratora, którego wartość w każdej iteracji jest zwiększana o 1. Aby to odwrócić, należy zdefiniować pętlę z opcją REVERSE: FOR iterator IN REVERSE 1..n LOOP END LOOP. Podstawowe typy danych w PL/SQL Podstawowe typy danych w PL/SQL NUMBER[(precision,scale)]: przechowuje liczby zarówno stałoprzecinkowe, jak zmiennoprzecinkowe. Parametr precision określa ilość cyfr całej liczby, parametr scale liczbę miejsc po przecinku. Zakres parametru precision wynosi 38 (domyślnie 38), skala może być z przedziału od -84 do 127(domyślnie 0). Liczbę całkowitą definiujemy następująco: NUMBER(p) lub NUMBER(p,0). Można też użyć podtypu INT. Liczby stałoprzecinkowe definiujemy podając obydwa parametry, liczby zmiennoprzecinkowe - tylko NUMBER, bez parametrów. CHAR(n) - typ znakowy stałej długości, n musi być z zakresu od 1 do 32767. Jeżeli nie zdefiniujemy zakresu, domyślnie przyjmowane jest n=1. VARCHAR2(n) - typ znakowy zmiennej długości, n musi być określone, zakres od 1 do 32767. BOOLEAN - typ logiczny, przechowuje tylko wartości TRUE, FALSE, i NULL (która odpowiada brakowi wartości lub wartości nieokreślonej). Na zmiennych typu BOOLEAN można wykonywać tylko operacje logiczne. DATE - przechowuje datę oraz czas.
Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u będziemy używać w taki sam sposób, jak wbudowanych funkcji Oracle. Funkcje tworzymy za pomocą instrukcji CREATE FUNCTION. CREATE FUNCTION nazwa_funkcji RETURN typ_zwracanych_danych deklaracje zmiennych kod RETURN wynik; Wywołanie funkcji może nastąpić z poziomu instrukcji SQL, np. SELECT nazwa_funkcji FROM dual; lub z poziomu innego programu PL/SQL. Usunięcie funkcji odbywa się za pomocą instrukcji DROP FUNCTION nazwa;. CREATE OR REPLACE FUNCTION suma RETURN INT liczba1 INT:=90; liczba2 INT:=100; suma INT; suma:=liczba1+liczba2; RETURN suma; Użycie parametrów w funkcjach Funkcje oraz procedury mogą mieć parametry. Wyróżniamy trzy typy parametrów: IN - parametr tylko do odczytu, służy do przekazania danych do funkcji lub procedury; OUT - parametr wyjściowy, umożliwia zwrócenie danych przez program; ma wartość NULL do momentu zainicjalizowania; IN OUT - parametr wejściowo/wyjściowy; podczas wywoływania programu służy do przekazania do niego danych, umożliwia zwrócenie danych; używamy, gdy dane wejściowe mają zostać zmienione podczas działania programu. Parametry wejściowe W funkcjach zazwyczaj używa się tylko parametrów typu IN. Definicja funkcji z uwzględnieniem parametrów wejściowych (IN) ma postać: CREATE FUNCTION nazwa_funkcji (parametr1 IN typ_danych, parametr2 IN typ_danych,...) RETURN typ_zwracanych_danych deklaracje zmiennych kod RETURN wynik; Uwaga. Używając typów CHAR, NUMBER, VARCHAR2 dla parametrów funkcji i procedur nie podajemy zakresu (jest wyliczany na podstawie danych wejściowych i wyjściowych).
Przykład funkcji liczącej średnią arytmetyczną dwóch liczb: CREATE OR REPLACE FUNCTION srednia (liczba1 IN NUMBER, liczba2 IN NUMBER) RETURN NUMBER srednia NUMBER; srednia:=(liczba1+liczba2)/2; RETURN srednia; Wywołanie funkcji srednia: SELECT srednia(1,2) FROM dual; Przykład funkcji, która pobiera ciąg reprezentujący kod pocztowy i zwraca wynik w formacie 99-999: CREATE OR REPLACE FUNCTION kod_pocztowy (kod IN char) RETURN char RETURN substr(kod,1,2) - substr(kod,3); Wywołanie funkcji kod: SELECT kod_pocztowy( 56009 ) FROM dual;