StoredProcedures_wykład Plik

Transkrypt

StoredProcedures_wykład Plik
Politechnika Śląska
Instytut Informatyki
LABORATORIUM BAZ DANYCH
IBM DB2 –
Procedury składowane
Opracowanie:
Aleksandra Werner
Gliwice 2005
Laboratorium Baz Danych. IBM DB2 – procedury
Spis treści
1
2
WPROWADZENIE ........................................................................................... 1
PODSTAWOWA STRUKTURA PROCEDURY ................................................ 3
2.1
Parametry ............................................................................................................................................. 4
2.1.1
Typy danych ................................................................................................................................. 4
2.2
Własności procedury ........................................................................................................................... 5
2.2.1
Otrzymywanie zbioru wynikowego .............................................................................................. 6
2.3
Parametry kontrolne procedury, kontrolujące sposób tworzenia procedury ................................ 7
2.4
Ciało procedury ................................................................................................................................... 7
2.4.1
Rejestry ......................................................................................................................................... 8
3
3.1
4
WYKONYWANIE PROCEDUR ........................................................................ 8
Dynamiczny SQL ................................................................................................................................. 9
ELEMENTY JĘZYKA SQL PL ......................................................................... 9
4.1
Sekwencje ........................................................................................................................................... 10
4.2
Instrukcje sterujące ........................................................................................................................... 10
4.3
Kursory ............................................................................................................................................... 11
4.3.1
Kursory FOR UPDATE .............................................................................................................. 12
4.3.2
Kursory WITH HOLD ................................................................................................................ 12
4.3.3
Kursory READ ONLY ............................................................................................................... 12
4.3.4
Kursory WITH RETURN ........................................................................................................... 13
4.4
Podstawowa obsługa błędów ............................................................................................................. 13
4.4.1
SQLCODE/SQLSTATE ............................................................................................................. 13
4.4.2
Deklaracja warunku i zgłoszenia CONDITION FOR ................................................................. 13
4.4.3
SIGNAL/RESIGNAL ................................................................................................................. 14
4.4.4
GET DIAGNOSTICS ................................................................................................................. 15
4.5
Złożony SQL ...................................................................................................................................... 15
5
5.1
5.2
PROCEDURY ................................................................................................. 16
External Stored Procedures .............................................................................................................. 16
Procedury rejestrowe (registering stored procedures) ................................................................... 16
6 SQL – PSM (ROZSZERZENIA PERSISTENT STORED MODULE) - JĘZYK
SKRYPTOWY DO DEKLARACJI I ZARZĄDZANIA PROCEDURAMI.................... 17
6.1
6.2
6.3
7
8
Kompilacja procedury ...................................................................................................................... 17
Etapy wdrażania procedur ............................................................................................................... 17
Opcje kompilacji i reoptymalizacji .................................................................................................. 17
KONCEPCJA NAZYWANIA PROCEDUR ..................................................... 18
UDF ................................................................................................................ 18
-2-
IBM DB2 – Procedury składowane
1
1
Wprowadzenie
Procedury składowane są obiektami aplikacji bazodanowej.
Procedury są nazwanymi blokami PL/SQL'a, które mogą pobierać parametry i być wykonywane. Rozróżnia
się dwa typy podprogramów: procedury i funkcje.
−
−
−
−
−
procedury pozwalają na enkapsulację kodu, co poprawia m.in. debugowanie
zmiany w schemacie bazy wpływają na zmianę kodu źródłowego tylko w jednym miejscu, co jest raczej
zadaniem DBA a nie rewizji całego kodu
ponieważ procedury składowane rezydują na serwerze, można za ich pomocą ściślej kontrolować
bezpieczeństwo przestrzeni klienta
ponieważ procedury składowane są kompilowane i przechowywane poza aplikacją, mogą używać takich
zmiennych w SQL-u jak: hasła i dane osobowe, których zwykle unika się w skryptach czy zdalnych
wywołaniach
redukują ruch w sieci.
DB2 pozwala na kodowanie procedur w dowolnym, potrzebnym języku. Istnieją dwa rodzaje procedur
składowanych:
1. procedury SQL
2. procedury zewnętrzne - zwykle pisane w C, a obecnie w Javie, COBOL-u, C++, Visual Basic-u,
REXX-ie. - jednym z typów są Java stored procedures.
Wywołanie procedury składowanej jest traktowane jako zwykłe wywołanie zewnętrzne. Procedura może
być wywoływana lokalnie (na tym samym systemie, co działająca aplikacja) lub na innym systemie. Procedury
składowane są użyteczne w środowisku rozproszonym, gdyż poprawiają wydajność rozproszonych aplikacji
przez redukcję ruchu informacji w sieci komunikacyjnej.
Np. jeżeli aplikacja kliencka potrzebuje wykonać kilka operacji bazodanowych na serwerze zdalnym, można
wydać wiele różnych żądań bazodanowych ze strony klienta lub wywołać procedurę składowaną.
W pierwszym przypadku startuje się dialog z systemem zdalnym za każdym razem, gdy wydaje się jakieś
żądanie. W przypadku drugim – tylko ządanie wywołania (call) i parametry przekazywane są po linii.
Tak więc procedury składowane mogą być używane dla różnych celów aplikacyjnych:
 wykonania sekwencji operacji na zdalnej maszynie
 kontroli dostępu do obiektów bazodanowych
 wykonania niebazodanowych funkcji
Wyobraźmy sobie następującą sytuację:
Pewne przedsiębiorstwo ma kilka central, w których znajdują się serwery i oddziałów, w których znajdują
się systemy klienckie. Użytkownicy oddziałów pracują na aplikacji FAKTURA, która aktualizuje 3 tabele na
serwerze:
1. tabelę FAKTURA
2. tabelę KLIENT
3. tabelę SALDO
Rekord faktury jest zaznaczany (flagowany) markerem „czyszczącym”, a następnie odpowiedni rekord tabeli
KLIENT jest aktualizowany przez odliczenie kwoty faktury od bieżącej (całkowitej) kwoty znajdującej się na
koncie. Na koniec, aktualizowane jest saldo.
Poniższy diagram ilustruje aplikację rozproszoną, która była zaimplementowana bez ??? procedur
składowanych.
IBM DB2 – Procedury składowane
2
Aplikacja rozproszona bez procedur
system klienta
Server
UPDATE
faktury
faktura
UPDATE
klienta
klient
UPDATE
salda
saldo
oddział
Aplikacja rozproszona z procedurą
Centrala
mojaproc
UPDATE
faktury
faktura
EXEC SQL
UPDATE
klienta
CALL mojaproc
ENDEXEC
klient
UPDATE
salda
saldo
Porównanie procedut składowanych, triggerów i UDF-ów.
Procedury składowane
wywołanie
środowisko
język
metoda
konwersacji
wykonanie polecenia
CALL
rozproszone/nierozproszone
aplikacje
jakikolwiek program
zawierający JAVA
jawne, dwustronne
przekazywanie parametrów
Triggery
UDF
bazodanowe WE/WY
jako funkcja w zdaniu SQL
rozproszone/nierozproszone
aplikacje
jakikolwiek program
zawierający JAVA
niejawne przesyłanie
parametrów systemu
rozproszone/nierozproszone
aplikacje
jakikolwiek program
zawierający JAVA
jawne, dwustronne
przekazywanie parametrów
DB2 ma swój język „DB2 SQL Procedural Language - SQL PL”. Ten język jest używany nie tylko w
procedurach składowanych, ale również w funkcjach użytkownika UDFs, triggerach i dynamicznym SQL-u.
Oto przykład procedury SQL, która może być użyta do kontroli operacji bazodanowej.
-2-
IBM DB2 – Procedury składowane
3
CREATE PROCEDURE administrator.update_sal
( IN empNum CHAR(6), IN rating SMALLINT)
LANGUAGE SQL
BEGIN
IF rating = 1 THEN
UPDATE employee
SET salary = salary * 1.10, bonus = 1500
WHERE empno = empNum;
ELSE
UPDATE employee
SET salary = salary * 1.05, bonus = 1000
WHERE empno = empNum;
END IF;
END
2
Podstawowa struktura procedury
Procedurę tworzy się przy użyciu polecenia CREATE PROCEDURE
Najprostsza procedura:
CREATE PROCEDURE proc01 ()
BEGIN
END @
CREATE PROCEDURE nazwa
( <lista parametrów>)
<właściwości procedury>
<parametry kontrolne procedury>
BEGIN
ciało_procedury
END
CREATE PROCEDURE nazwa
( | IN | OUT | INOUT parametr typ)
LANGUAGE SQL
dla LUW nie trzeba
[EXTERNAL ACTION | NO EXTERNAL ACTION] tylko dla LUW - wtedy, gdy akcja zmienia stan
obiektu nie zarządzanego przez DB2
[SPECIFIC nazwa_specyfikacji czyli inaczej unikalna nazwa procedury]
[DYNAMIC RESULT SETS liczba]
[NOT DETERMINISTIC | DETERMINISTIC]
[CALLED ON NULL INPUT]
BEGIN
ciało_procedury
END
Kiedy nazwa procedury nie jest kwalifikowana, schemat procedury jest wyznaczany na podstawie schematu
bieżącego - czyli autoryzowanego identyfikatora bieżącego użytkownika.
-3-
IBM DB2 – Procedury składowane
4
Kwalifikowane nazwy - np.
db2admin.reademp.
Uwaga! Nie może to być schemat SYS!
2.1
Parametry
Definicja parametrów składa się z 3 części:
1. trybu definiującego czy parametr jest WE (IN), WY (OUT), czy WE/WY (INOUT). Parametr w
trybie INOUT pozwala przekazać wartość do wywoływanego podprogramu i zwrócić wartość na
zewnątrz wywoływanego podprogramu. Wewnątrz programu taki parametr zachowuje się
zainicjowana zmienna
2. nazwy parametru
3. SQL-owego typu i rozmiaru danych tego parametru
CREATE PROCEDURE update_pensja
(IN nr_prac INTEGER,
IN procent_wzrostu DECIMAL(4,2),
INOUT ilosc_prac INTEGER,
OUT zaktualizowana_pensja DECIMAL(5,2))
Procedura może też nie mieć żadnych parametrów, a nawiasy mogą być wtedy pominięte.
...
CREATE PROCEDURE update_pensja LANGUAGE SQL BEGIN ...
lub:
CREATE PROCEDURE update_pensja() LANGUAGE SQL BEGIN ..
2.1.1
Typy danych
Mogą być typy 2 kategorii:
−
−
wbudowane - Integer (Smallint, Bigint), Decimal (Numeric), Real (Double), Char, Varchar, CLOB (1bajtowe Character Large Object), GRAPHIC, DBCLOB (2-bajtowe Character Large Object), BLOB (Binary
Large Objects), Date, Time, Timestamp, ROWID (iSeries)
użytkownika - UDT (User-defined Data Types).
Dla typów wbudowanych String można specyfikować podtypy - np. kolumny CHAR i VARCHAR mogą
być definiowane jako FOR BIT DATA żeby przechowywać dane binarne.
Do tworzenia typów UDT używa się:
CREATE DISTINCT TYPE nazwa AS źródłowy_typ_danych WITH COMPARISIONS
Klauzula WITH COMPARISIONS pozwala na użycie operatorów dostarczonych przez system dla
źródłowych typów danych. Ta klauzula nie jest dozwolona dla typów źródłowych: BLOB, CLOB, DBCLOB,..
Niech przykładowo zdefiniowano 2 zmienne:
DECLARE v_w_milach DOUBLE;
DECLARE v_w_kilometrach DOUBLE;
Chcę zapobiec wykoniu nieprawidłowej operacji typu:
* IF (v_w_milach > v_w_kilometrach) - (nie mogę porównać bez konwersji)
Mogę wobec tego stworzyć 2 typy:
-4-
IBM DB2 – Procedury składowane
5
CREATE DISTINCT TYPE mile AS DOUBLE WITH COMPARISIONS
CREATE DISTINCT TYPE kilometry AS DOUBLE WITH COMPARISIONS
Teraz mogę zadeklarować zmienne:
DECLARE v_w_milach MILE;
DECLARE v_w_kilometrach KILOMETRY;
... i teraz dostanę błąd SQL-owy jeżeli wykonam *.
W momencie stworzenia UDT, DB2 generuje 2 funkcje rzutowania ???????:
−
−
jedna rzutuje z UDt na typ źródłowy - MILE (DOUBLE)
druga rzutuje na odwrót - DOUBLE (MILE).
Podobnie się dzieje dla KILOMETRY.
Tak więc, żeby zadziałało polecenie:
IF (v_w_milach > 30.0)
trzeba napisać:
IF (v_w_milach > MILE (DOUBLE(v_w_kilometrach)/1,6))
IF (v_w_milach >MILE(30.0))
2.2
Własności procedury
Własności procedury to: język, liczba oczekiwanych zbiorów wynikowych, itd.
Klauzula SPECIFIC jest ważna, kiedy wymagana jest definicja procedury o tej samej nazwie, ale z inną
liczbą parametrów - tzw. przeładowanie - ale dotyczy to tylko iSeries i LUW (Linux, Unix i Windows).
CREATE PROCEDURE suma (IN p_a INTEGER, IN p_b INTEGER, OUT p_s INTEGER)
LANGUAGE SQL
SPECIFIC suma_ab
BEGIN
SET p_s = p_a + p_b;
END
CREATE PROCEDURE suma (IN p_a INTEGER, IN p_b INTEGER, IN p_c INTEGER, OUT p_s INTEGER)
LANGUAGE SQL
SPECIFIC suma_abc
BEGIN
SET p_s = p_a + p_b + p_c;
END
Podczas wywołania procedury suma DB2 wyznacza wersję procedury na podstawie liczby parametrów.
CALL suma(100, 200, ?)
-5-
IBM DB2 – Procedury składowane
6
Natomiast niedozwolone jest definiowanie procedur p tej samej nazwie z tą samą liczbą parametrów
różnego typu.
Co trzeba zrobić, żeby usunąć taką „przeładowaną” procedurę?
−
−
wyspecyfikować parametry procedury w poleceniu DROP PROCEDURE np. DROP PROCEDURE suma(INTEGER, INTEGER, INTEGER)
użyć DROP SPECIFIC PROCEDURE - np. DROP SPECIFIC PROCEDURE suma_ab
Taka nazwa specyfikacji może też być użyta w zdaniu COMMENT ON np. COMMENT ON SPECIFIC PROCEDURE suma_abc IS ‘To jest 3-parametrowa wersja procedury’
W LUW jeżeli nazwa specyfikacji nie jest podana jawnie podczas tworzenia procedury, DB2 generuje
unikalną nazwę składającą się z SQL i znacznika czasowego:SQLyymmddhhmmsshhn
Klauzula DETERMINISTIC pozwala na określenie procedury, która zwraca te same wyniki dla każdego
wywołania z identycznymi parametrami wejściowymi i ma służyć dalszej poprawie wydajności.
Klauzula CALLED ON NULL INPUT oznacza, że procedura będzie zawsze wywoływana nawet, jeżeli jej
parametry wejściowe będą NULL-ami.
W opcji RESULT SETS podaje się maksymalną liczbę zbiorów wynikowych.
2.2.1
Otrzymywanie zbioru wynikowego
Żeby zwrócić zbiór wynikowy do aplikacji wywołującej, procedura potrzebuje deklaracji kursora dla wybranych
wierszy. Wiele zbiorów wynikowych może być zwróconych, ale każdy z nich wymaga niezależnego zdania DECLARE
CURSOR.
Przykład:
CREATE PROCEDURE GetCusName()
RESULT SETS 1 tu podaję max. liczbę zbiorów wyn.
LANGUAGE SQL
BEGIN
DECLARE c1 CURSOR WITH RETURN FOR kursor użyto po to, aby zwrócić zbiór
SELECT nazwisko FROM klient ORDER BY nazwisko
OPEN c1;
END
DECLARE rs1 RESULT_SET_LOCATOR VARYING;
CALL procedure1();
ASSOCIATE RESULT SET LOCATOR (rs1, rs2)
WITH PROCEDURE procedure1;
ALLOCATE cursor1 CURSOR FOR RESULT SET rs1;
ALLOCATE cursor2 CURSOR FOR RESULT SET rs2;
FETCH FROM cursor1 INTO var1, var2 ;
FETCH FROM cursor2 INTO var3 ;
Kursor jest zamykany przez program wywołujący po zwróceniu zbioru wynikowego.
-6-
IBM DB2 – Procedury składowane
2.3
7
Parametry kontrolne procedury, kontrolujące sposób tworzenia procedury
Ustawia się je poleceniem SET OPTION. Do tych parametrów zalicza się:
− DBGVIEW - generuje informacje do debugowania,
− OUTPUT - wylistowuje wyjście,
− TGTRLS - generuje kod dla OS/400.
2.4
Ciało procedury
BEGIN
DECLARE <deklaracja_zmiennych>
DECLARE CURSOR <deklaracja_kursorów>
<deklaracja_wyjątków>
<zdania_SQL>
END
Dobrym zwyczajem jest wstawianie komentarzy:
--
−
poprzedzanych symbolami
−
otoczonych - jak w C - symbolami /* .... */
Zmienne muszą być deklarowane na początku bloku BEGIN/END przed jakimikolwiek zdaniami SQL. W
przeciwnym wypadku wystąpi błąd. Zmienne muszą mieć nazwę różną od nazw kolumn tych tabel, do których
odwołuje się procedura (ale błąd nie wystąpi). Najlepiej poprzedzać nazwy zmiennych v_ a nazwy parametrów
p_. Po zadeklarowaniu zmiennych, są one inicjalizowane NULL-ami, chyba, że użyta zostanie klauzula
DEFAULT inicjalizująca zmienną pewną wartością.
DECLARE v_nr_prac VARCHAr(6);
DECLARE v_total, v_liczba INTEGER DEFAULT 0;
Można ustawić wartość pojedynczej zmiennej używając SET, lub poleceń SELECT i FETCH w kombinacji
z INTO. Polecenie VALUES używane jest do wyliczenia wartości rejestru i związania z nią pewnej zmiennej.
SET v_total = v_total + 1
SELECT max(pensja) INTO v_max FROM prac;
VALUES CURRENT DATE INTO v_date;
Przykład prostej procedury, aktualizującej zbiór nowym nazwiskiem klienta na podstawie numeru i nowego
nazwiska klienta:
CREATE PROCEDURE update_klient
(IN nr CHARACTER(5),
IN nazwisko CHARACTER(20))
LANGUAGE SQL
UPDATE klient SET nazw_klienta = nazwisko WHERE nr_klienta = nr;
-7-
IBM DB2 – Procedury składowane
2.4.1
8
Rejestry
W DB2 istnieją specjalne rejestry, będące rejestrami pamięciowymi pozwalającymi DB2 dostarczać
aplikacji informacji o jej środowisku. Do tych rejestrów można się odwoływać w zdaniach SQL.
modyfikowalneM
niemodyfikowalne
Najczęściej używa się następujących rejestrów:
−
−
−
−
−
−
−
−
−
−
−
CURRENT DATE - data na serwerze
CURRENT TIME CURRENT TIMESTAMP CURRENT ISOLATION - poziom izolacji dla dynamicznego zdania SQL w ramach bieżącej sesji
CURRENT LOCK TIMEOUT - liczba sekund, które aplikacja musi odczekać żeby uzyskać blokadę - można
modyfikować M
CURRENT PATH - można modyfikować M. Ścieżka jest listą schematów, które DB2 (kolejno!) przeszukuje
żeby zlokalizować procedurę. Domyślną ścieżką w LUW jest: ‘SYSIBM’, ‘SYSFUN’, ‘SYSPROC’,
‘DB2ADMIN’
CURRENT PACKAGE PATH - M
CURRENT SCHEMA - M nazwa schematu używana do kwalifikowania niekwalifikowanych obiektów
bazodanowych. Można modyfikować przez SET CURRENT SCHEMA
USER - ID autoryzacji używany do połączenia z bazą
SESSION USER - ID autoryzacji używany dla bieżącego schematu - jest synonimem do rejestru USER
SYSTEM USER - ID autoryzacji użytkownika połączonego z bazą.
Żeby uzyskać wartość rejestru, należy użyć komendy SELECT, natomiast żeby zaktualizować
modyfikowalny rejestr, należy użyć komendy SET.
SELECT CURRENT SCHEMA FROM SYSIBM.SYSDUMMY1;
SET CURRENT SCHEMA = db2admin
Oto przykład procedury tworzącej tabelę datetab w celu demonstracji użycia specjalnych rejestrów w
SQL-u.
CREATE PROCEDURE registersample
(OUT p_start TIMESTAMP, OUT p_end TIMESTAMP,
OUT p_c1 TIMESTAMP, OUT p_c2 TIME, OUT p_user CHAR(20))
LANGUAGE SQL
SPECIFIC rejestrsample
BEGIN
CREATE TABLE datetab (c1 TIMESTAMP, c2 TIME, c3 DATE);
VALUES CURRENT TIMESTAMP INTO p_start;
INSERT INTO datetab VALUES (CURRENT TIMESTAMP, CURRENT TIME, CURRENT DATE + 3 DAYS);
SELECT c1, c2 INTO p_c1, p_c2 FROM datetab;
VALUES CURRENT TIMESTAMP INTO p_end;
SET p_user = USER;
DROP TABLE datetab;
END
3
Wykonywanie procedur
Uprawnienia, które musi mieć user:
GRANT EXECUTE ON SPECIFIC PROCEDURE <nazwa procedury> TO USER <user>
-8-
IBM DB2 – Procedury składowane
9
Uprawnienia, które musi mieć developer:
GRANT <operacje> ON <obiekty> TO USER <user>
GRANT BINDADD ON <baza danych> TO USER <user>
Polecenie CREATE PROCEDURE nie ma opcji “replace”, więc jeżeli chcę zastąpić istniejącą definicję procedury
należy użyć DROP PROCEDURE.
Procedurę wywołuje się poleceniem CALL, natomiast to polecenie wywołuje zewnętrzną procedurę:
EXEC SQL
CALL hsale (:param1, :param2, :param3, :param4)
END-EXEC
Utworzenie z okna komend:
db2 –td@ -f simple.sql
db2 call proc01()
3.1
Dynamiczny SQL
W dynamicznym SQL-u polecenia są znane jedynie podczas wykonywania. Żeby pracować z dynamicznym SQL-em
wykorzystuje się polecenia:
− PREPARE – bierze zmienną VARCHAR zawierającą polecenie SQL i konwertuje je na polecenie
wykonywalne
− EXECUTE – pozwala wykonać poprzednio przygotowane polecenie PREPARE zdanie
− EXECUTE IMMEDIATE – przygotowuje i wykonuje polecenie zawarte w stringu. Np.
EXECUTE IMMEDIATE ‘UPDATE tabela SET ...’
DECLARE statement1 STATEMENT;
SET string1 = ’UPDATE tab1 SET col1 = ? ’ || ’WHERE col2 = ?’ ;
PREPARE statement1 FROM string1 ;
EXECUTE statement1 USING var1,var2
3.1.1
Dynamiczny SQL - kursory
DECLARE statement1 STATEMENT;
DECLARE cursor1 CURSOR FOR statement1;
SET string1 = ’SELECT column1 FROM tab1 ’ || ’WHERE column2 = ’ || CHAR( variable1) ;
PREPARE statement1 FROM string1 ;
OPEN cursor1;
3.2
Dynamiczny SQL - parametryzowanie
-- Złóżmy, że sygnatura procedury wygląda: schema1.procedure1(IN,INOUT,OUT)
-9-
IBM DB2 – Procedury składowane
10
DECLARE statement1 STATEMENT;
SET string1 = ’CALL schema1.procedure1’ || ’(?,?,?)’ ;
PREPARE statement1 FROM string1 ;
EXECUTE statement1 INTO var1,var2 USING var3,var4;
USING
VAR3
VAR4
CALL PROCEDURE1
?
?
?
definicja
IN
INOUT
OUT
VAR1
VAR2
INTO
Elementy języka SQL PL
4
4.1
Sekwencje
Sekwencje są obiektami, które pozwalają automatycznie generować wartości.
CREATE SEQUENCE nazwa_sekwencji AS INTEGER | typ_danych
START WITH wart_numeryczna
INCREMENT BY wart_numeryczna
MINVALUE wart_numeryczna
MAXVALUE wart_numeryczna [NO CYCLE | CYCLE]
Do generacji i uzyskania wartości sekwencji używane są wyrażenia: NEXT VALUE i PREVIOUS VALUE.
VALUES PREVIOUS VALUE FOR sek1 INTO ...
4.2
1.
Instrukcje sterujące
pętle FOR, WHILE, LOOP, REPEAT



pętla FOR
nazwa pętli loop_name może być użyta do kwalifikowania zmiennych odnoszących się do wartości kolumn w
związanym z FOR kursorze. Pętla ta jest używana tylko do przetwarzania wierszy tabel - tzn. przetwarzania
każdego wiersza zwróconego przez podaną instrukcję SELECT.
FOR loop_name AS SELECT kol1, kol2, …
DO
SET var1 = loop_name.col1;
…
END FOR;
pętla WHILE
WHILE (var1 = 1) DO
…
END WHILE;
pętla LOOP
- 10 -
IBM DB2 – Procedury składowane


2.
może być zdefiniowana etykieta bloku LOOP. Wewnątrz pętli musi być wyspecyfikowana opcja
LEAVE, żeby można było wyjść z pętli (ale mogę też wyjść deklarując handler - zgłoszenie). Z
kolei opcja ITERATE wymusza następną iterację w pętli.
etykieta: LOOP
…
LEAVE etykieta;
…
ITERATE etykieta;
END LOOP;
pętla REPEAT
REPEAT
…
UNTIL (var1 < 100)
END REPEAT;
“pętla” GOTO - GOTO zastępuje ITERATE.
GOTO etykieta;
RETURN int_value
instrukcje warunkowe
 Dopuszcza się stosowanie trzech form instrukcji IF: IF-THEN, IF-THEN-ELSE, i IF-THEN-ELSEIF

4.3
11
IF v_var = 1 THEN
UPDATE …
ELSE
INSERT …
END IF;
instrukcja CASE
można ją użyć na 2 sposoby:
CASE
WHEN v_var = 0 THEN …
WHEN v_var = 10 THEN …
ELSE …
END CASE;
CASE v_var
WHEN 0 THEN ...
WHEN 10 THEN ...
ELSE ...
END CASE
Kursory
SQL PL niejawnie deklaruje kursor dla wszystkich instrukcji manipulowania danymi, włączając zapytania zwracające
tylko jeden wiersz. Dla zapytań zwracających więcej niż jeden wiersz można jawnie zadeklarować kursor przetwarzający
indywidualnie wiersze.
- 11 -
IBM DB2 – Procedury składowane
12
DECLARE SQLSTATE CHAR(5);
DECLARE cursor1 CURSOR FOR select … ;
-- Po deklaracji zmiennych
OPEN cursor1;
FETCH FROM cursor1 INTO var1, var2, … ;
WHILE (SQLSTATE = ’00000’)
DO
…
END WHILE;
CLOSE cursor1;
DB2 niejawnie otwiera kursor do przetwarzania każdej instrukcji SQL'a nie połączonej z jawnie zadeklarowanym
kursorem. SQL PL pozwala odwoływać się do ostatniego niejawnego kursora jak do kursora SQL. Tym samym można
używać atrybutów kursora w celu pozyskania informacji o ostatnio wykonanej instrukcji SQL.
4.3.1
Kursory FOR UPDATE
Instrukcja OPEN wykonuje zapytanie skojarzone z jawnie zadeklarowanym kursorem. Otwarcie kursora wykonuje
zapytanie i identyfikuje aktywny zbiór, który zawiera wiersze spełniające kryterium wyszukiwania.
Dla kursorów zadeklarowanych z użyciem klauzuli FOR UPDATE, instrukcja OPEN blokuje te wiersze.
DECLARE SQLSTATE CHAR(5);
DECLARE cursor1 CURSOR FOR
select … FOR UPDATE;
-- domniemana wartość: FOR READ ONLY
OPEN cursor1;
FETCH FROM cursor1 INTO var1, var2, … ;
WHILE (SQLSTATE = ’00000’)
DO
DELETE FROM tab1 WHERE CURRENT OF cursor1;
…
UPDATE tab1 SET … WHERE CURRENT OF cursor1;
END WHILE;
4.3.2
Kursory WITH HOLD
Te kursory są zachowywane po COMMIT.
DECLARE cursor1 CURSOR WITH HOLD FOR select … FOR UPDATE;
COMMIT;
-- teraz kursory nie będą zamknięte
ROLLBACK;
-- wszystkie kursory są zamykane
-- wszystkie blokady są zwalniane
-- lokatory BLOB-ów są zwalniane
4.3.3
Kursory READ ONLY
Nie będzie zakłądana blokada EXCLUSIVE LOCK
- 12 -
IBM DB2 – Procedury składowane
4.3.4
13
Kursory WITH RETURN
Tylko dla aplikacji bazy z OS/390.
Podstawowa obsługa błędów
4.4
W DB2 są następujące typy poleceń, zgłaszających błąd:
1. zmienne SQLCODE i SQLSTATE
2. deklaracje warunku i zgłoszenia (handlera)
3. polecenia SIGNAL i RESIGNAL
4. GET DIAGNOSTICS EXCEPTION
4.4.1
SQLCODE/SQLSTATE
W DB2 są 2 zmienne, których DBMS używa do identyfikacji błędu:
1.
2.
SQLSTATE - kod standaryzowany - niezależny od platformy. Ma 5 znaków, z czego 2 pierwsze
reprezentują klasę błędu, a pozostałe 3 - szczegółowe warunki błędu (podklasę błędu).
SQLCODE - tak DB2 raportuje błąd i ostrzeżenia - sposób oryginalny DB2.
Jeżeli jest błąd, to SQLCODE jest < 0, SQLSTATE ≠ 00 | 01 | 02
Jeżeli jest ostrzeżenie, to SQLCODE jest > 0 i pierwsze 2 cyfry SQLSTATE = 01 | 02
Jeżeli jest wszystko w porządku, to SQLCODE = 0 i SQLSTATE = 00000
DECLARE SQLSTATE CHAR(5) DETAULT ’00000’;-- ISO/ANSI SQL92
-- ’00xxx’ – sukces
-- ’01xxx’ – ostrzeżenie
-- ’02xxx’ – not found
-- other – błąd
DECLARE SQLCODE INT DETAULT 0; -- DB2 specific
-- 0 – sukces
-- >0 – ostrzeżenie
-- 100 – not found
-- <0 – błąd
Są też oczywiście błędy definiowane przez użytkownika. Np. pracownik nie może zarabiać więcej od swojego
kierownika. Błędy te są kodowane w SQLSTATE przez pierwsze znaki ‘38’.
4.4.2
Deklaracja warunku i zgłoszenia CONDITION FOR
Jakie są typowe sytuacje wymagające jawnego zgłoszenia błędu?
− w SELECT-cie nie ma żadnych wierszy
− nastąpiło naruszenie więzów integralności w poleceniu UPDATE lub DELETE
− itd.
Więc piszę:
DECLARE record_not_found CONDITION FOR ;02000’ – record_not_found to nazwa warunku
DECLARE check_constraint_error CONDITION FOR ‘23513’
Po słowie CONDITION FOR występuje wzięty numer z SQLSTATE. Wtedy deklarowany warunek wystąpi, gdy np.
SQLSTATE = ‘23513’.
- 13 -
IBM DB2 – Procedury składowane
14
Żeby użyć nazwy warunku trzeba zadeklarować zgłoszenie, a potem – kiedy handler jest zdefiniowany/zadeklarowany –
można podjąć jedną z 3 akcji:
CONTINUE - sterowanie przechodzi do polecenia znajdującego się za tym poleceniem, które wywołało
błąd.
2. EXIT - sterowanie jest przekazywane na koniec SQL złożonego
3. UNDO - wykonywana jest operacja rollback na złożonym SQL zaczynającym się od BEGIN ATOMIC.
Przykład:
1.
DECLARE not_found CONDITION FOR ‘02000’
DECLARE CONTINUE HANDLER FOR not_found
SET at_end = 1
Poza predefiniowanymi w SQLSTATE handlerami można też definiować wyjątki w następujących sytuacjach:
− SQLEXCEPTION
− SQLWARNINGS
− NOT FOUND
Oto przykład typowego bloku poleceń na początku procedury:
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET v_sqlcode = SQLCODE;
DECLARE UNDO HANDLER FOR SQLWARNING
SET v_sqlcode = SQLCODE;
DECLARE EXIT HANDLER FOR NOT FOUND
SET v_sqlcode = SQLCODE;
Ogólna postać:
DECLARE condition-name CONDITION FOR SQLSTATE ’xxxxx’ ;
Przykład:
DECLARE not_found CONDITION FOR SQLSTATE ’02000’ ;
4.4.3
SIGNAL/RESIGNAL
SIGNAL jawnie sygnalizuje warunek błędu/ostrzeżenia. Jeżeli jest definiowane zgłoszenie żeby zgłosić wyjątek, jest to
wywoływane natychmiast przez polecenie SIGNAL. Sterowanie przechodzi wtedy do zdefiniowanego zgłoszenia błędu.
Przykład:
SIGNAL SQLSTATE ‘38001’ – zgłoszenie będzie uruchomione
Polecenie RESIGNAL zwraca SQLSTATE i SQL MESSAGE TEXT do wywołującej zgłoszenie aplikacji. To polecenie
ustawia wiadomość diagnozującą.
Przykład:
RESIGNAL SQLSTATE ‘38TNF’ SET MESSAGE TEXT = ‘nie znaleziono pracownika’
Przykład zaawansowanej obsługi:
DECLARE EXIT HANDLER FOR SQLSTATE = ‘xxxxx’
RESIGNAL SQLSTATE ‘xxxxx’ SET MESSAGE TEXT = ‘.....’
Ostatni przykład:
SIGNAL SQLSTATE ’xxxxx’;
--------------------------------------------DECLARE condition1 CONDITION FOR SQLSTATE ’99001’;
- 14 -
IBM DB2 – Procedury składowane
15
IF (pojawił się błąd) THEN
SIGNAL condition1
SET MESSAGE_TEXT = Twój komunikat błędu’;
4.4.4
GET DIAGNOSTICS
GET DIAGNOSTICS EXCEPTION jest używany w celu umożliwienia dostępu do informacji związanej z
błędem/ostzreżeniem.
Samo GET DIAGNOSTICS może też być użyte do pozyskania informacji o liczbie wierszy przetworzonych przez
instrukcje: INSERT, UPDATE, DELETE.
Przykład:
GET DIAGNOSTICS num_record = ROW_COUNT
4.5
Złożony SQL
Złożony SQL pozwala grupować wiele poleceń (zwykle INSERT, UPDATE i DELETE) w jeden
wykonywalny blok. Taki blok poleceń może być wykonany jako pojedynczy strumień, co redukuje czas
wykonania i ruch w sieci. Złożony SQL nie gwarantuje porządku wykonania poleceń składowych, tak więc
należy unikać wzajemnych zależności między poleceniami.
Ogólna struktura zdania złożonego:
etykieta: BEGIN
<lista lokalnych deklaracji zmiennych>
< lista lokalnych deklaracji kursora>
<lista lokalnych deklaracji zgłoszeń - handlerów>
<polecenia SQL>
END;
jak widać można etykietować:
lab1: BEGIN
DECLARE v_id INT;
lab2: BEGIN
DECLARE v_id INT;
SET lab1.v_id = 1;
SET lab2.v_id = 10;
SET v_id = 100;
END lab2;
END lab1
BEGIN ATOMIC
DECLARE v_var2 INTEGER;
CREATE TABLE mytab(id INT);
CREATE INDEX mytab_idx ON mytab(id);
BEGIN
DECLARE v_var4 INTEGER DEFAULT 100;
INSERT INTO mytab(id) VALUES (99),(v_var4);
GET DIAGNOSTICS v_var2 = ROW_COUNT;
SET p_result = 'Number of rows: ' ||
char(v_var2);
END; -- średnik jest wymagany
END
- 15 -
IBM DB2 – Procedury składowane
16
BEGIN ATOMIC
…
-- SQL’e traktowane są jak jedno polecenie. Nie mogę tu użyć COMMIT i ROLLBACK
END;
-- nieobsłużony błąd -> zatrzymanie procedury. ->-- wszystkie zmiany są anulowane
--------------------------------------------BEGIN NOT ATOMIC -- to jest domniemana wart.
…
COMMIT;
ROLLBACK;
ROLLBACK TO SAVEPOINT sp1;
…
END;
-- nieobsłużony błąd -> zatrzymanie procedury ->-- Zmiany pozostają. Ręczne wycofanie lub zatwierdzenie
5
5.1
Procedury
External Stored Procedures
Zewnętrzna procedura składowana jest pisana przez użytkownika w jednym z języków programowania C, COBOL,
RPG, FORTRAN, JAVA, C++, REXX, ... na serwerze iSeries. Żeby stworzyć zewnętrzną procedurę, kod źródłowy dla
języka hosta musi być skompilowany, tak więc tworzony jest obiekt program. Wtedy używane jest polecenie CREATE
PROCEDURE, które podpowiada systemowi gdzie znajduje się obiekt program, który implementuje tą procedurę.
Czyli najpierw - przed użyciem zewnętrznej procedury - musi być ona zarejestrowana w bazie, np. przez CREATE
PROCEDURE.
Np. procedura zwracająca nazwisko dostawcy, który miesięcznie i rocznie sprzedaje najwięcej produktów.
EXEC SQL
CREATE PROCEDURE hsale
(IN rok INTEGER,
IN miesiąc INTEGER,
OUT nazwisko_dostawcy CHAR(20),
OUT hsale DECIMAL(11,2))
EXTERNAL NAME sproclib.hsales
LANGUAGE RPGLE
PARAMETER STYLE GENERAL
END_EXEC
5.2
Procedury rejestrowe (registering stored procedures)
Czym się różni polecenie CREATE PROCEDURE od DECLARE PROCEDURE? W CREATE procedura i definicje
parametrów dodawane są do systemowych tabel katalogu - SYSROUTINES, i SYSPARMS (1 wiersz na 1 parametr). Jest
też tabela SYSPROC. Tak więc procedura zaczyna być dostępna dla jakiegokolwiek programu klienckiego chodzącego na
lokalnym lub zdalnym systemie. Czyli CREATE PROCEDURE potrzebuje być wykonane tylko raz w swoim życiu.
Natomiast DECLARE jest głównie używane do tymczasowej rejestracji procedury w programie.
SELECT * FROM QSYS2.SYSROUTINES;
- 16 -
IBM DB2 – Procedury składowane
17
SQL – PSM (rozszerzenia persistent stored module) - Język skryptowy do deklaracji i
zarządzania procedurami
6
SQL PSM może być użyty w:
6.1

Procedurach składowanych, które są wywoływane poleceniem CALL.

Triggerach – automatycznie wywoływanych kiedy zajdzie zdarzenie aktywujące.

Funkcjach definiowanych przez użytkownika.
Kompilacja procedury
Skompilowany kod oraz opcjonalnie kod źródłowy procedury przechowany jest w katalogach systemowych.
Jednocześnie tworzony jest pakiet, w którym przechowywane są plany wykonania statycznych poleceń SQL.
CREATE PROCEDURE OUT_MEDIAN (
OUT medianSalary DOUBLE,
OUT maxSalary DOUBLE)
DYNAMIC RESULT SETS 0
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
Parsing and
compilation
SQL PL
pseudo code
DECLARE v_numRecords INT DEFAULT 1 ;
DECLARE v_salary1 DOUBLE DEFAULT 0 ;
DECLARE c1 CURSOR FOR
SELECT CAST(salary AS DOUBLE) FROM staff
ORDER BY salary;
6.2
Procedure text
Package
DB2
System Catalogs
Etapy wdrażania procedur
-- REBIND – powtórne przygotowanie planów
-- zapytań statycznych SQL-i
CALL SYSPROC.REBIND_ROUTINE_PACKAGE ('P', 'MYSCHEMA.MYPROC', 'CONSERVATIVE')
-- Przeniesienie skompilowanego kodu
-- procedury do pliku
GET ROUTINE INTO file1 FROM SPECIFIC PROCEDURE proc1 HIDE BODY ;
-- Wgranie skompilowanej procedury do bazy:
PUT ROUTINE FROM file1 ;
6.3
Opcje kompilacji i reoptymalizacji
db2set DB2_SQLROUTINE_PREPOPTS=
BLOCKING {UNAMBIG | ALL | NO}
DATETIME {DEF | USA | EUR | ISO | JIS | LOC}
DEGREE {1 | degree-of-parallelism | ANY}
- 17 -
IBM DB2 – Procedury składowane
18
DYNAMICRULES {BIND | RUN}
EXPLAIN {NO | YES | ALL}
EXPLSNAP {NO | YES | ALL}
FEDERATED {NO | YES}
INSERT {DEF | BUF}
ISOLATION {CS |RR |UR |RS |NC}
QUERYOPT optimization-level
VALIDATE {RUN | BIND}
-- na poziomie instancji;
-- wymagany db2stop,db2start
VALUES GET_ROUTINE_OPTS() ;
-- bieżące parametry kompilacji
CALL SET_ROUTINE_OPTS
('VALIDATE RUN ISOLATION UR') ;
-- ustawienie dla bieżącej sesji
CALL SET_ROUTINE_OPTS(NULL)
-- przywrócenie domniemanych ustawień
7
Koncepcja nazywania procedur
xxxxLEP
L- język
E - środowisko: N - Windows
4 - AS/400
M - OS/390
P - cel:
C - klient
S - procedura SQL
8
UDF
Wyróżniamy 2 rodzaje:
4.
5.
funkcje skalarne - zwracają pojedynczą, skalarną wartość; mogą być typu:
−
źródłowe - zarejestrowane w bazie, odwołujące się do innej funkcji
−
SQL - napisane w SQL
−
zewnętrzne - napisane w pewnym języku wysokiego poziomu
funkcje tabel
CREATE FUNCTION nazwa
<deklaracja parametrów>
RETURNS
SPECIFIC
LANGUAGE
BEGIN
<ciało funkcji>
RETURN
END
- 18 -

Podobne dokumenty