background image

Bazy danych – wykład dwunasty

PL/SQL, c.d.

Konrad Zdanowski

Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

1 / 37

background image

SQL to za mało

SQL brakuje mo˙zliwo´sci dost ˛epnych w j ˛ezykach proceduralnych.

W SQL wywołujemy pojedy ´ncze polecenia.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

2 / 37

background image

PL/SQL

J ˛ezyk proceduralny.

Zintegrowany z SQL.

Mo˙zliwo´s´c składowania procedur i funkcji w bazie danych.

Stosowany zarówno po stronie serwera jak i w aplikacjach
klientów.
Pozwala na korzystanie z bibliotek,

I

np. I/O - set serveroutput on.

Pozwala na dynamiczne konstruowanie zapyta ´n SQL w trakcie
wykonywania procedury.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

3 / 37

background image

PL/SQL – posta´c programu

DECLARE
...
BEGIN
....
EXCEPTION
...
END;

W programie musz ˛

a wyst ˛

api´c tylko

BEGIN END.

Pozostałe cz ˛e´sci s ˛

a opcjonalne.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

4 / 37

background image

Kursory

PL/SQL nie umo˙zliwia zapyta ´n SQL, które zwracaj ˛

a całe tabele

(zawieraj ˛

ace wi ˛ecej ni˙z jeden wiersz).

Je´sli chcemy wykona´c inne zapytanie, musimy u˙zy´c kursora.

Kursor to zmienna, która przebiega zbiór wyników zapytania.

Rodzaje kursorów: jawne i niejawne.

Z ka˙zdym zapytaniem SQL zwi ˛

azany jest kursor niejawny.

Kursor jawny deklarujemy w bloku DECLARE.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

5 / 37

background image

Kursory jawne – deklarowanie

cursor nazwa ( parametry ) i s

{ z a p y t a n i e |

r e t u r n t y p }

[

f o r update of parametry ] ] ;

Parametry podajemy jako list ˛e oddzielona przecinkami:

parametr t y p [

d e f a u l t w a r t o s c ]

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

6 / 37

background image

Kursory jawne

Zanim zaczniemy u˙zywa´c kursora musimy go otworzy´c komend ˛

a:

open nazwa_kursora ( parametry ) ;

Po zako ´nczeniu pracy kursor zamykamy:

close nazwa_kursora ;

Próba otwarcia otwartego kursora generuje bł ˛

ad, podobnie

zamkni ˛ecie nieotwartego kursora.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

7 / 37

background image

Kursory jawne – pobieranie rekordów

Kursor mo˙zemy traktowa´c jako zmienn ˛

a typu rekordowego

przebiegaj ˛

ac ˛

a zbiór wyników kwerendy.

Aby odczyta´c krotk˛e u˙zywamy instrukcji:

I

fetch kursor into lista zmiennych,

I

fetch kursor into zmienna rekordowa.

Zmienne przyjmuj ˛

a warto´s´c krotki, na któr ˛

a wskazuje kursor.

Kursor przechodzi do nast ˛epnej krotki.

Je´sli kursor przeczytał wszystkie krotki wyst ˛

api bł ˛

ad.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

8 / 37

background image

Kursory jawne – pobieranie rekordów

declare
cursor 
cur_osoby i s

s e l e c t ∗ from osoby ;

osoba osoby%

rowtype ;

nazwisko osoby . nazwisko%

type ;

i m i e osoby . i m i e%

type ;

i d osoby . i d%

type ;

begin

open cur_osoby ;

f e t c h cur_osoby i n t o i m i e , nazwisko , i d ;

dbms_output . p u t _ l i n e ( i m i e

| |

’ | | nazwisko | | ’

’ | |

t o _ c h a r ( i d ) ) ;

f e t c h cur_osoby i n t o osoba ;

dbms_output . p u t _ l i n e

( osoba . i m i e | | ’

’ | | osoba . nazwisko | | ’

’ | |

t o _ c h a r ( osoba . i d ) ) ;

close cur_osoby ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

9 / 37

background image

Typy danych

Mo˙zemy zadeklarowa´c zmienn ˛

a typu atrybutu jako

R.atrybut%type, gdzie R to tabela lub kursor.

Mo˙zemy zadeklarowa´c zmienn ˛

a typu krotki jako R%rowtype,

gdzie R to tabela lub kursor.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

10 / 37

background image

Kursory jawne – atrybuty

Stan kursora mo˙zemy sprawdzi´c poprzez jego atrybuty:

%ISOPEN,

%FOUND – przyjmuje warto´sci true, false lub null (przed
pierwszym pobraniem),

%NOTFOUND,

%ROWCOUNT – liczba pobranych rekordów (zero przed
pobraniem).

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

11 / 37

background image

Kursory jawne – atrybuty

declare
cursor 
cur_osoby i s

s e l e c t ∗ from osoby ;

osoba osoby%

rowtype ;

begin

i f not cur_osoby%is ope n ) then

open cur_osoby ;

end i f ;

loop

f e t c h cur_osoby i n t o osoba ;

e x i t when cur_osoby%n o t f o u n d ;

dbms_output . p u t _ l i n e ( osoba . i m i e

| |

’ | | osoba . nazwisko | | ’

’ | |

t o _ c h a r ( osoba . i d ) ) ;

end loop ;

close cur_osoby ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

12 / 37

background image

Kursory jawne – p ˛etla

for

Mo˙zemy w łatwiejszy sposób przebiec wszystkie wyniki zapytania
w p ˛etli

for:

f o r l i c z n i k i n k u r s o r

loop

. . .

end loop ;

W tej konstrukcji nie musimy otwiera´c ani zamyka´c kursora.

Zamiast kursora mo˙zemy u˙zy´c zapytania SQL.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

13 / 37

background image

Kursory jawne – p ˛etla

for

declare
cursor 
cur _osob y_imi e ( imie_osoby

varchar2 d e f a u l t

’ Jan ’ )

i s

s e l e c t ∗ from osoby where osoby . i m i e =imie_osoby ;

begin

f o r c u r i n cur _osob y_imi e

loop

dbms_output . p u t _ l i n e ( c u r . i m i e

| | ’

| |

c u r . nazwisko | |

| |

t o _ c h a r ( c u r . i d ) ) ;

end loop ;
end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

14 / 37

background image

Kursory jawne – modyfikacje tabel

Mo˙zemy zadeklarowa´c kursor jako

for update.

Kursor taki zakłada blokad ˛e na wszystkie rekordy, które mo˙ze
zmodyfikowa´c.

Mo˙zemy modyfikowa´c rekord, który został aktualnie odczytany
przez kursor.

update t a b e l a set . . .

where c u r r e n t of c u r _ t a b e l a ;

d e l e t e from t a b e l a

where c u r r e n t of c u r _ t a b e l a ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

15 / 37

background image

Kursory niejawne

Ka˙zde polecenie SQL (select into, insert, update, delete) tworzy
kursor.

Nazwa kursora to sql.

Sprawdzaj ˛

ac jego własno´sci mo˙zemy sprawdzi´c własno´sci

ostatniego zapytania, np. sql%rowcount zwraca liczb ˛e krotek
zapytania.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

16 / 37

background image

Wyj ˛

atki

Je´sli w czasie wykonywania programu PL/SQL wyst ˛

api bł ˛

ad,

działanie programu zostaje przerwane.

Program mo˙ze przechwyci´c obsług ˛e błedu w cz ˛e´sci

exception.

Program mo˙ze zgłosi´c te˙z własny wyj ˛

atek przez:

raise nazwa_wyj ˛

atku.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

17 / 37

background image

Wyj ˛

atki

Wyj ˛

atki prefefiniowane:

cursor_already_open,

invalid_cursor,

no_date_found,

too_many_rows,

value_error,

zero_divide.

W cz ˛e´sci obsługuj ˛

acej wyj ˛

atki mo˙zemy u˙zy´c:

when others aby

obsłu˙zy´c wyj ˛

atki, których wcze´sniej nie wymienilismy.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

18 / 37

background image

Wyj ˛

atki u˙zytkownika

Wyj ˛

atki definiujemy w cz ˛esci

declare przez

nazwa_wyjatku

exception;

Zgłaszamy przez

raise nazwa_wyjatku.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

19 / 37

background image

Obsługa wyj ˛

atków – sterowanie

declare
cursor 
cur_osoby i s s e l e c t ∗ from osoby

osoba osoby%

rowtype ;

begin

begin

open cur_osoby ; open cur_osoby ;

dbms_output . p u t _ l i n e ( ’ T u t a j s t e r o w a n i e n i e d o t r z e ’ ) ;

exception

when c u r s o r _ a l r e a d y _ o p e n then

close cur_osoby ; dbms_output . p u t _ l i n e ( ’ Zamknieto k u r s o r ’ ) ;

end ;

dbms_output . p u t _ l i n e ( ’ T u t a j wraca s t e r o w a n i e ’ ) ;
close cur_osoby ;
exception

when i n v a l i d _ c u r s o r then

dbms_output . p u t _ l i n e ( ’ Zabroniona o p e r a c j a na k u r s o r z e ’ ) ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

20 / 37

background image

Obsługa wyj ˛

atków – sterowanie

Po obsłu˙zeniu wyjatku sterowanie wraca do bloku programu, który
wywołał program, w którym powstał wyj ˛

atek.

Raz obsłuzony wyj ˛

atek nie jest obsługiwany wy˙zej.

Nie obsłu˙zony wyj ˛

atek powoduje przerwanie programu i

zgłoszenie bł ˛edu aplikacji.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

21 / 37

background image

Obsługa wyj ˛

atków – sterowanie

Je´sli wyj ˛

atek powstanie w sekcji

declare, to sterowanie wraca do

programu, który wywołał program, który zgłosił wyj ˛

atek.

Podobnie zachowuj ˛

a si ˛e wyj ˛

atki powstałe w cz ˛e´sci obsługuj ˛

acej

wyj ˛

atki.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

22 / 37

background image

Obsługa wyj ˛

atków – sterowanie

begin

declare

i

number ( 3 ) : = 1 0 0 0 ;

begin

n u l l ;

exception

when v a l u e _ e r r o r then

dbms_output . p u t _ l i n e ( ’ Z l a w a r t o s c ’ ) ;

−− t u t a j s t e r o w a n i e n i e d o t r z e

end ;

n u l l ;

exception

when v a l u e _ e r r o r then

dbms_output . p u t _ l i n e ( ’ T u t a j n a s t e p u j e obsluga w y j a t k u ’ ) ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

23 / 37

background image

Obsługa wyj ˛

atków – przykład

cr ea te t a b l e Kura (

i d

i n t primary key ,

j a j k o _ i d

i n t

) ;

cr ea te t a b l e J a j k o (

i d

i n t primary key ,

k u r a _ i d

i n t

) ;

a l t e r t a b l e Kura add c o n s t r a i n t KuraRefJajko

f o r e i g n key ( j a j k o _ i d ) references J a j k o ( i d )

i n i t i a l l y deferred d e f e r r a b l e ;

a l t e r t a b l e J a j k o add c o n s t r a i n t JajkoRefKura

f o r e i g n key ( k u r a _ i d ) references Kura ( i d )

i n i t i a l l y deferred d e f e r r a b l e ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

24 / 37

background image

Obsługa wyj ˛

atków – przykład

cr ea te or replace

t r i g g e r D o d a j J a j k o

before update or i n s e r t on Kura

f o r each row

declare

i

number ;

begin

s e l e c t i d i n t o from J a j k o

where k u r a _ i d = :new . k u r a _ i d ;

exception

when no_data_found then

i n s e r t i n t o J a j k o values ( : new . j a j k o _ i d , n u l l ) ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

25 / 37

background image

Składowane programy

Przechowywane po skompilowaniu w BD.

Procedury, funkcje, wyzwalacze, pakiety.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

26 / 37

background image

Składowane programy – parametry

Pozwalaj ˛

a przekazywa´c warto´sci do programu i z programu.

Paremetry programu w deklaracji nazywamy formalnymi, przy
wywołaniu programu aktualnymi.

Typy parametrów to

inoutin out.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

27 / 37

background image

Składowane programy – składnia

cr ea te or replace ] nazwa_procedury [ ( parametry ) ] i s

d e k l a r a c j e

begin

. . .

end [ nazwa_procedury ] ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

28 / 37

background image

Składowane programy – składnia

cr ea te or replace ] n a z w a _ f u n k c j i [ ( parametry ) ]

r e t u r n t y p [ i s as ]

d e k l a r a c j e

begin

. . .

end [ n a z w a _ f u n k c j i ] ;

Funkcja powinna zawiera´c

return. Po wykonaniu tej instrukcji

wychodzimy z funkcji.

Funkcji mo˙zemy u˙zy´c w zapytaniu SQL.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

29 / 37

background image

Składowane programy – parametry

Parametry deklarujemy jako:

nazwa_parametru

[ t r y b p r z e k a z a n i a ] t y p

[ {

d e f a u l t w a r t o s c ] .

Typy parametrów to:

in – domy´slny tryb, przekazuje warto´s´c do programu, parametr
zachowuje si ˛e jak stała,

out – parametr musi by´c zmienn ˛

a, traktujemy j ˛

a jako zmienn ˛

a

niezainicjowan ˛

a, przekazuje warto´s´c na zewn ˛

atrz procedury,

in out – zmienna zainicjowana przekazuj ˛

aca warto´s´c na zewn ˛

atrz.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

30 / 37

background image

Składowane programy – przykład

cr ea te or replace procedure

i n k r e m e n t a c j a ( n

i n out number )

r e t u r n number i s

begin

n : = n + 1 ;

r e t u r n ( n ) ;

end i n k r e m e n t a c j a ;

Teraz mo˙zemy procedur ˛e wywoła´c:

declare

n

number : = 3 ;

i

number ;

begin

−− t u t a j n = 3

i : = i n k r e m e n t a c j a ( n ) ;

−− t u t a j n = 4

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

31 / 37

background image

Pakiety

cr ea te or replace package nazwa_pakietu i s

d e k l a r a c j e zmiennych , s t a l y c h ,

kursorow , f u n k c j i , procedur ,

. . .

end ;

cr ea te or replace package body nazwa_pakietu i s

d e k l a r a c j e zmiennych , s t a l y c h ,

kursorow n i e d o s t e p n y c h w i n t e r f e j s i e p a k i e t u ,

d e f i n i c j e

f u n k c j i

i p r o c e d u r

end ;

Funkcje i procedury z pakietu wywołujemy jako:
nazwa_pakietu.nazwa_programu().

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

32 / 37

background image

Dynamiczny SQL

Je´sli nie znamy podczas kompilacji pytania SQL, mo˙zemy je
skonstruowa´c podczas wykonywania programu.

Typowe sytuacje to: nie znamy nazwy tabeli, z której b ˛edziemy
pobiera´c dane, nie znamy warunku.

Dynamiczny SQL jest mniej efektywny i bardziej podatny na błedy
(np. podczas kompilacji zapytania).

Mo˙zemy te˙z w ten sposób wywoływa´c programy PL/SQL.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

33 / 37

background image

Dynamiczny SQL – przykład

cr ea te or replace procedure wloz_osoba (

osoba_id

i n out number ,

i m i e

i n varchar2 ,

nazwisko

i n varchar2 as

begin

osoba_id : = osoby_seq . n e x t v a l ;

i n s e r t i n t o osoby values ( osoba_id , i m i e , nazwisko ) ;

end ;

declare

plsql_komenda

varchar2 ( 5 0 0 ) ;

nowe_imie

varchar2 ( 5 0 ) : = ’ Jan ’ ;

nowe_nazwisko

varchar2 ( 1 0 0 ) : = ’ K o w a l s k i ’ ;

begin
plsql_komenda : =

’ beg in wloz_osoba ( : a , : b , : c ) ; end ; ’ ;

execute immediate plsql_komenda

using i n out nowe_id , nowe_imie , nowe_nazwisko ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

34 / 37

background image

Dynamiczny SQL – przykład

Nie mo˙zna przekaza´c stałej

null ale mo˙zna przekaza´c zmienn ˛

a,

która ma t ˛

a warto´s´c.

Trzeba uwa˙za´c na typy przekazywanych zmiennych, by były
zgodne z SQL, np. nie mo˙zna u˙zy´c w tworzonym zapytaniu SQL
zmiennej o typie

boolean.

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

35 / 37

background image

Dynamiczny SQL – parametry

Je´sli wywołujemy zapytanie SQL, to nie s ˛

a istotne nazwy u˙zytych

w definicji parametrów.
Ten kod wstawi do tabeli osoby pana Jana Nowaka:

begin

s q l _ z a p y t a n i e : =

’ i n s e r t i n t o osoby v a l u e s ( : x , : x , : y ) ’ ;

execute immediate s q l _ z a p y t a n i e

using 18 , ’ Jan ’ ,

’ Nowak ’ ;

end ;

Je´sli wywołujemy program PL/SQL nazwy parametrów s ˛

a istotne.

Ten kod obliczy warto´s´c funkcja(a,b,a):

begin

s q l _ z a p y t a n i e : = ’ be gin f u n k c j a ( : x , : y , : x ) ’ ;

execute immediate s q l _ z a p y t a n i e using

a , b ;

end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

36 / 37

background image

Dynamiczny SQL – przykład

declare
type 
KursorTyp i s r e f cursor ;
cur_osoby KursorTyp ;

v _ s t r

varchar2 ( 2 0 0 ) ;

osoba osoby%

rowtype ;

begin

v _ s t r : = ’ s e l e c t ∗ from osoby where i m i e = : i ’ ;

open cur_osoby f o r v _ s t r using ’Ewa ’ ;

loop

f e t c h cur_osoby i n t o osoba ;

e x i t when cur_osoby%n o t f o u n d ;

dbms_output . p u t _ l i n e ( osoba . i m i e

| |

| |

osoba . nazwisko ) ;

end loop ;
end ;

Konrad Zdanowski ( Uniwersytet Kardynała Stefana Wyszy ´nskiego, Warszawa)

Bazy danych – wykład dwunasty PL/SQL, c.d.

37 / 37