Datenbankanwendung
Wintersemester 2014/15
Prof. Dr.-Ing. Sebastian Michel
TU Kaiserslautern
smichel@cs.uni-kl.de
Embedded SQL
Übersicht der (kommenden) Vorlesungen
Embedded SQL (in Java und C++)
Stored Procedures und User-Defined Functions
Database Triggers
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
2 / 54
Embedded SQL
Wiederholung: JDBC: Connect und einfache Anfrage
// r e g i s t r i e r e g e e i g n e t e n T r e i b e r ( h i e r f u e r P o s t g r e s q l )
C l a s s . forName ( ” o r g . p o s t g r e s q l . D r i v e r ” ) ;
// e r z e u g e V e r b i n d u n g z u r Datenbank
C o n n e c t i o n conn = D r i v e r M a n a g e r . g e t C o n n e c t i o n (
” jdbc : postgresql :// l o c a l h o s t / u n i v e r s i t y ” ,
” use r n a m e ” , ” p a s s w o r d ” ) ;
// e r z e u g e e i n e i n f a c h e s S t a t e m e n t O b j e k t
S t a t e m e n t s t m t = conn . c r e a t e S t a t e m e n t ( ) ;
// m i t e x e c u t e Query koennen nun d a r a u f A n f r a g e n a u s g e f u e h r t
werden
// E r g e b n i s s e i n Form e i n e s R e s u l t S e t O b j e k t s
R e s u l t S e t r s e t = s t m t . e x e c u t e Q u e r y ( ”SELECT p . p e r s n r from
p r o f e s s o r e n p” ) ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
3 / 54
Embedded SQL
Wiederholung: JDBC: Connect und einfache Anfrage
// d i e s e s b e s i t z t Metadaten
R e s u l t S e t M e t a D a t a m e t a d at a = r s e t . getMetaData ( ) ;
// w e l c h e A t t r i b u t e ( S p a l t e n ) b e s i t z e n d i e E r g e b n i s −T u p e l ?
i n t c o l u m n c o u n t = m e ta d at a . getColumnCount ( ) ;
f o r ( i n t i n d e x =1; i n d e x <=c o l u m n c o u n t ; i n d e x ++) {
System . o u t . p r i n t l n ( ” S p a l t e ”+i n d e x+” h e i s s t ” +
m e t a d a t a . getColumnName ( i n d e x ) ) ;
}
// i t e r i e r e nun u e b e r E r g e b n i s s e
while ( r s e t . next () ) {
System . o u t . p r i n t l n ( r s e t . g e t S t r i n g ( 1 ) ) ;
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
4 / 54
Embedded SQL
Call-level-Interface (CLI)
Unter Verwendung einer Bibliothek werden aus dem
Anwendungsprogramm (Wirtssprache) Funktionen aufgerufen, die mit
dem DBMS kommunizieren.
JDBC ist ein Beispiel für ein CLI
Im embedded SQL werden hingegen SQL Anweisungen direkt in der
Wirtssprache benutzt.
(Dennoch werden diese letztendlich durch Aufrufe von
DBMS-spezifischen Bibliotheken realisiert)
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
5 / 54
Embedded SQL
Embedded SQL (ESQL)
Idee
Benutze SQL-Anweisungen direkt im Programmcode
Syntax in Java:
#s q l { <s q l −s t a t e m e n t > } ;
Syntax in C oder C++
EXEC SQL <s q l −s t a t e m e n t >;
Zum Beispiel:
EXEC SQL
SELECT vorname , nachname
INTO : vorname , : nachname
FROM m i t a r b e i t e r t a b e l l e
WHERE p n r = : p n r ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
6 / 54
Embedded SQL
SQLJ
SQLJ: Embedded SQL für Java
Einbettung von SQL in Java
Anweisungen der Form
#s q l { <s q l −s t a t e m e n t > } ;
Zum Beispiel:
#s q l {INSERT INTO emp ( ename , s a l )
VALUES ( ' Joe ' , 4 3 0 0 0 ) } ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
7 / 54
Embedded SQL
SQLJ
SQLJ: Embedded SQL für Java
Idee
SQL Anweisungen werden direkt im Java Code benutzt (embedded)
Ein Precompiler übersetzt diesen gemischten Code (in *.sqlj
Dateien) in normalen Java Code (in *.java Dateien).
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
8 / 54
Embedded SQL
SQLJ
SQLJ: Schritte der Übersetzung
Quelle:
https://docs.oracle.com/cd/B28359_01/java.111/b31227/overview.htm
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
9 / 54
Embedded SQL
SQLJ
SQLJ: Vor- und Nachteile im Vergleich zu JDBC
Vorteile
Einfacher (kompakter) Code
Verwendung der gleichen Variablen in SQL und in Java
Nachteile
Erfordert extra Übersetzung in “normales” Java.
Umsetzung/Unterstützung
Wird von Oracle angeboten (im eigenen DBMS)
Sonst kaum (nicht) anzutreffen
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
10 / 54
Embedded SQL
SQLJ
Beispiel
https://docs.oracle.com/cd/B28359_01/java.111/b31227/overview.htm
1
import j a v a . s q l . * ;
2
3
4
5
6
7
8
/* *
T h i s i s what you h a v e t o do i n SQLJ
* */
p u b l i c c l a s s SimpleDemoSQLJ
{
//TO DO: make a main t h a t c a l l s t h i s
9
10
11
12
13
14
15
16
17
p u b l i c A d d r e s s g e t E m p l o y e e A d d r e s s ( i n t empno )
throws S Q L E x c e p t i o n
{
Address addr ;
#s q l { SELECT o f f i c e a d d r INTO : a d d r FROM e m p l o y e e s
WHERE empnumber = : empno } ;
return addr ;
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
11 / 54
Embedded SQL
SQLJ
Beispiel
18
pub lic Address updateAddress ( Address addr )
throws S Q L E x c e p t i o n
{
#s q l a d d r = { VALUES(UPDATE ADDRESS ( : a d d r ) ) } ;
return addr ;
}
19
20
21
22
23
24
25
}
Vergleichbarer Code in JDBC ist um einiges länger
Siehe obige URL (Oracle)
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
12 / 54
Embedded SQL
Embedded SQL in C/C++
Embedded SQL in C/C++
Weit verbreitet, wird von vielen DBMS unterstützt
Postgresql: ECPG compiler
Oracle: Pro*C/C++ compiler
Embedded SQL ist standardisiert. Dies gilt allerdings nicht für
Spracherweiterungen wie Oracles PL/SQL oder Postgresqls PL/pgSQL.
Microsoft hat mit LINQ (Language Integrated Query) einen zu embedded
SQL ähnlichen Ansatz für das .NET Framework entwickelt.
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
13 / 54
Embedded SQL
Embedded SQL in C/C++
Beispiel
1
#i n c l u d e < s t d i o . h>
2
3
4
5
6
7
EXEC SQL BEGIN DECLARE SECTION ;
i n t matrnr ;
c h a r name [ 1 0 2 4 ] ;
i n t matrnrBound ;
EXEC SQL END DECLARE SECTION ;
8
9
10
11
i n t main ( )
{
EXEC SQL CONNECT TO u n i x : p o s t g r e s q l : / / l o c a l h o s t / u n i v e r s i t y ;
12
13
14
// s e l e c t f o r s i n g l e r e s u l t i t e m s , o t h e r w i s e u s e c u r s o r s
EXEC SQL SELECT m a t r n r INTO : m a t r n r from s t u d e n t e n where
name = ' F i c h t e ' ;
15
16
p r i n t f ( ” m a t r n r=%s \n ” , m a t r n r ) ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
14 / 54
Embedded SQL
Embedded SQL in C/C++
Beispiel (2)
// nun e i n e A n f r a g e , d i e m e h r e r e E r g e b n i s s e
17
liefert
18
matrnrBound = 2 7 0 0 0 ;
19
20
EXEC SQL DECLARE m y c u r s o r CURSOR FOR
SELECT matrnr , name
FROM s t u d e n t e n
WHERE m a t r n r < : matrnrBound
ORDER BY s e m e s t e r ;
21
22
23
24
25
26
EXEC SQL OPEN m y c u r s o r ;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1) {
EXEC SQL FETCH m y c u r s o r INTO : matrnr , : name ;
p r i n t f (”% i \ t%s \n ” , matrnr , name ) ;
}
EXEC SQL CLOSE m y c u r s o r ;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL ;
return 0;
27
28
29
30
31
32
33
34
35
36
37
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
15 / 54
Embedded SQL
Embedded SQL in C/C++
Embedded SQL in C/C++
ECPG
http://www.postgresql.org/docs/9.3/interactive/
ecpg-commands.html
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
16 / 54
Embedded SQL
Embedded SQL in C/C++
Übersetzen von embedded SQL Code
Das Tool ecpg ist der Precompiler für Postgresqls embedded C.
Eingabe ist eine Quellcode-Code in C mit eingebetteten SQL
Befehlen.
Ausgabe ist C-Code (Datei), der mittels der ECPG Bibliothek in der
Lage ist mit der Postgresql Datenbank zu kommunizieren.
Übersetzung von embedded SQL in reines C:
ecpg test.c -o test_parsed.c
Kombilieren des C-Codes:
gcc test_parsed.c -o test -I /usr/include/postgresql/ -lecpg
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
17 / 54
Embedded SQL
Embedded SQL in C/C++
Übersetzter ECPG Code
Nur zur Veranschaulichung!
1
2
3
4
5
6
/ * P r o c e s s e d by e c p g ( 4 . 8 . 0 ) * /
/ * These i n c l u d e f i l e s a r e added by t h e p r e p r o c e s s o r * /
#i n c l u d e < e c p g l i b . h>
#i n c l u d e <e c p g e r r n o . h>
#i n c l u d e <s q l c a . h>
/ * End o f a u t o m a t i c i n c l u d e s e c t i o n * /
7
8
#l i n e 1 ” t e s t . c ”
9
10
#i n c l u d e < s t d i o . h>
11
12
/* e x e c s q l b e g i n d e c l a r e s e c t i o n */
13
14
15
#l i n e 6 ” t e s t . c ”
i n t matrnr ;
16
17
18
#l i n e 7 ” t e s t . c ”
c h a r name [ 1024 ] ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
18 / 54
19
20
21
22
Embedded SQL
Embedded SQL in C/C++
Übersetzter ECPG Code (2)
#l i n e 8 ” t e s t . c ”
i n t matrnrBound ;
/ * e x e c s q l end d e c l a r e s e c t i o n * /
#l i n e 9 ” t e s t . c ”
23
24
25
26
27
i n t main ( )
{
{ ECPGconnect ( L I N E , 0 , ” u n i x : p o s t g r e s q l : / / l o c a l h o s t /
u n i v e r s i t y ” , NULL , NULL , NULL , 0 ) ; }
#l i n e 14 ” t e s t . c ”
28
29
30
// a s con1 USER s m i c h e l ;
//EXEC SQL CONNECT TO u n i x : p o s t g r e s q l : / / l o c a l h o s t /
u n i v e r s i t y AS m y c o n n e c t i o n USER s m i c h e l ;
31
32
33
34
35
// s e l e c t f o r s i n g l e r e s u l t i t e m s , o t h e r w i s e u s e c u r s o r s
{ ECPGdo ( L I N E , 0 , 1 , NULL , 0 , ECPGst normal , ” s e l e c t
m a t r n r from s t u d e n t e n where name = ' F i c h t e ' ” , ECPGt EOIT ,
ECPGt int ,&( m a t r n r ) , ( l o n g ) 1 , ( l o n g ) 1 , s i z e o f ( i n t ) ,
ECPGt NO INDICATOR , NULL , 0L , 0L , 0L , ECPGt EORT ) ; }
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
19 / 54
36
37
Embedded SQL
Embedded SQL in C/C++
Übersetzter ECPG Code (3)
#l i n e 19 ” t e s t . c ”
p r i n t f ( ” m a t r n r=%i \n” , m a t r n r ) ;
38
39
// nun e i n e A n f r a g e , d i e m e h r e r e E r g e b n i s s e z u r u e c k
liefert
40
41
matrnrBound = 2 7 0 0 0 ;
42
43
44
/ * d e c l a r e m y c u r s o r c u r s o r f o r s e l e c t m a t r n r , name from
s t u d e n t e n where m a t r n r < $ 1 o r d e r by s e m e s t e r * /
#l i n e 31 ” t e s t . c ”
45
46
47
48
49
{ ECPGdo ( L I N E , 0 , 1 , NULL , 0 , ECPGst normal , ” d e c l a r e
m y c u r s o r c u r s o r f o r s e l e c t m a t r n r , name from s t u d e n t e n
where m a t r n r < $ 1 o r d e r by s e m e s t e r ” ,
ECPGt int ,&( matrnrBound ) , ( l o n g ) 1 , ( l o n g ) 1 , s i z e o f ( i n t ) ,
ECPGt NO INDICATOR , NULL , 0L , 0L , 0L , ECPGt EOIT ,
ECPGt EORT ) ; }
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
20 / 54
50
51
52
Embedded SQL
Embedded SQL in C/C++
Übersetzter ECPG Code (4)
#l i n e 33 ” t e s t . c ”
/* e x e c s q l w h e n e v e r n o t f o u n d
#l i n e 34 ” t e s t . c ”
b r e a k ; */
53
54
55
56
57
58
59
60
while (1) {
{ ECPGdo ( L I N E , 0 , 1 , NULL , 0 , ECPGst normal , ”
f e t c h m y c u r s o r ” , ECPGt EOIT ,
ECPGt int ,&( m a t r n r ) , ( l o n g ) 1 , ( l o n g ) 1 , s i z e o f ( i n t ) ,
ECPGt NO INDICATOR , NULL , 0L , 0L , 0L ,
ECPGt char , ( name ) , ( l o n g ) 1 0 2 4 , ( l o n g ) 1 , ( 1 0 2 4 ) * s i z e o f ( c h a r ) ,
ECPGt NO INDICATOR , NULL , 0L , 0L , 0L , ECPGt EORT ) ;
#l i n e 36 ” t e s t . c ”
61
62
63
i f ( s q l c a . s q l c o d e == ECPG NOT FOUND) break ; }
#l i n e 36 ” t e s t . c ”
64
p r i n t f ( ”%i \ t%s \n” , matrnr , name ) ;
65
66
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
21 / 54
67
68
Embedded SQL
Embedded SQL in C/C++
Übersetzter ECPG Code (5)
{ ECPGdo ( L I N E , 0 , 1 , NULL , 0 , ECPGst normal , ” c l o s e
m y c u r s o r ” , ECPGt EOIT , ECPGt EORT ) ; }
#l i n e 40 ” t e s t . c ”
69
70
71
{ ECPGtrans ( L I N E
#l i n e 41 ” t e s t . c ”
, NULL , ” commit ” ) ; }
72
73
74
{ ECPGdisconnect (
#l i n e 42 ” t e s t . c ”
LINE
, ”ALL” ) ; }
75
return 0;
76
77
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
22 / 54
Embedded SQL
Embedded SQL in C/C++
Aufbau einer Verbindung zur DB
#i n c l u d e < s t d i o . h>
i n t main ( )
{
EXEC SQL CONNECT TO
u n i x : p o s t g r e s q l : // l o c a l h o s t / u n i v e r s i t y ;
// . . .
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL ;
return 0;
}
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
23 / 54
Embedded SQL
Embedded SQL in C/C++
Aufbau einer Verbindung zur DB (2)
Es können auch mehrere Verbindungen aufgebaut werden und via
Namen benutzt werden:
EXEC SQL CONNECT TO
u n i x : p o s t g r e s q l : // l o c a l h o s t / u n i v e r s i t y ;
AS conn1 ;
Weitere Parameter wie Login, Passwort, Port sind natürlich ebenfalls
möglich
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
24 / 54
Embedded SQL
Embedded SQL in C/C++
Host-Variablen
Die sogennanten Host-Variablen sind Variablen, die gemeinsam vom
Programmcode und SQL Anweisungen benutzt werden können.
Der Name der C/C++ Variablen wird in SQL mit einem Doppelpunkt als
Präfix benutzt. Z.B.
EXEC SQL INSERT INTO s o m e t a b l e VALUES ( : v1 ,
' f o o ' , : v2 ) ;
Deklaration
Host-Variablen müssen speziell deklariert werden:
EXEC SQL BEGIN DECLARE SECTION ;
i n t x =4;
char foo [ 1 6 ] , bar [ 1 6 ] ;
EXEC SQL END DECLARE SECTION ;
http://www.postgresql.org/docs/9.3/interactive/
ecpg-variables.html
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
25 / 54
Embedded SQL
Embedded SQL in C/C++
Transaktionen
Abschließen einer Transaktion
EXEC SQL COMMIT
Rollback der aktuellen Transaktion
EXEC SQL ROLLBACK
Ein- bzw. Abschalten des automatischen Commits
EXEC SQL SET AUTOCOMMIT TO ON
EXEC SQL SET AUTOCOMMIT TO OFF
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
26 / 54
Embedded SQL
Embedded SQL in C/C++
Arbeiten mit Cursorn
Gibt eine Anweisung mehrere Zeilen zurück müssen Cursor benutzt
werden. In JDBC-Terminologie ist ein ResultSet ein Cursor.
....
matrnrBound = 2 7 0 0 0 ;
EXEC SQL DECLARE m y c u r s o r CURSOR FOR
SELECT matrnr , name
FROM s t u d e n t e n
WHERE m a t r n r < : matrnrBound
ORDER BY s e m e s t e r ;
Die Host-Variable matrnBound wird hier direkt in der SQL-Anweisung
benutzt.
Man könnte auch eine parametrisierte SQL Anweisung benutzten.
Wie wurde diese Klasse in JDBC genannt?
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
27 / 54
Embedded SQL
Embedded SQL in C/C++
Arbeiten mit Cursorn (2)
Der Cursor muss nun nur noch geöffnet werden
Dann kann via FETCH auf die einzelnen Tupel bzw. Spalten
zugegriffen werden.
// c u r s o r w i r d g e o e f f n e t
EXEC SQL OPEN m y c u r s o r ;
// was s o l l g e s c h e h e n wenn k e i n e E r g e b n i s s e g e l i e f e r t werden ?
EXEC SQL WHENEVER NOT FOUND DO BREAK;
// s o l a n g e k e i n BREAK a u f g e r u f e n w i r d l a u f e u e b e r Z e i l e n
while (1) {
EXEC SQL FETCH m y c u r s o r INTO : matrnr , : name ;
p r i n t f (”% i \ t%s \n ” , matrnr , name ) ;
}
// c u r s o r w i r d g e s c h l o s s e n
EXEC SQL CLOSE m y c u r s o r ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
28 / 54
Embedded SQL
Embedded SQL in C/C++
Prepared-Statements
Ähnlich zu JDBC können wir auch in embedded SQL Prepared-Statements
benutzen.
EXEC SQL PREPARE s t m t 1 FROM ”SELECT o i d , datname FROM
p g d a t a b a s e WHERE o i d = ? ” ;
Bei der (bzw. vor der) Ausführung müssen dann die freien Parameter
gesetzt werden. Zudem wird erst jetzt angegeben in welchen
Host-Variablen die Attribute des Ergebnis-Tupels gespeichert werden soll.
EXEC SQL EXECUTE s t m t 1 INTO : d b o i d , : dbname USING 1 ;
Wenn das Prepared-Statement nicht mehr gebraucht wird:
EXEC SQL DEALLOCATE PREPARE name ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
29 / 54
Embedded SQL
Embedded SQL in C/C++
Prepared-Statements und Cursor
Hier wird ein Prepared-Statement erzeugt und dann ein Cursor darüber
definiert:
EXEC SQL PREPARE s t m t 1 FROM ”SELECT o i d , datname FROM
p g d a t a b a s e WHERE o i d > ? ” ;
EXEC SQL DECLARE f o o b a r CURSOR FOR s t m t 1 ;
// wenn Ende e r r e i c h t i s t , m i t t e l s BREAK a u s While−S c h l e i f e
aussteigen
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL OPEN f o o b a r USING 1 0 0 ;
...
while (1)
{
EXEC SQL FETCH NEXT FROM f o o b a r INTO : d b o i d , : dbname ;
...
}
EXEC SQL CLOSE f o o b a r ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
30 / 54
Embedded SQL
Embedded SQL in C/C++
Allgemein: Prepared-Statements, Static vs. Dynamic SQL
Übersetzung von Anfragen im DBMS
Tritt eine Anfrage zum ersten Mal auf, muss sie “übersetzt” werden
(compiled).
D.h. Syntaxprüfung, Prüfung von Rechten, Anfrageoptimierung,
Code-Generierung, etc.
Wiederverwendung von kompilierten Anfragen
Sind Anfragen parametrisiert, wie im Falle von Prepared-Statements,
so kann das DBMS den bereits erzeugten Plan wiederverwenden.
Im Vergleich zu nicht parametrisierten Statements, fallen hier die
Kosten für die Übersetzung nur ein Mal an.
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
31 / 54
Embedded SQL
Embedded SQL in C/C++
Allgemein: Prepared-Statements, Static vs. Dynamic SQL
Wiederverwendung von kompilierten Anfragen
DBMS prüft bei Eintreffen einer Anfrage ob Plan bereits existiert.
Dazu werden Pläne in Cache gehalten (→Ersetzungsstrategien)
Neu-Kompilierung bestehender Pläne
Falls sich Eigenschaften der DB ändern die essentiell für Plangenerierung
sind. Zum Beispiel:
Indexe werden hinzugefügt oder gelöscht.
Sehr viele Änderungen an Daten der relevanten Tabellen
Explizite Anweisungen neu zu kompilieren, bzw.
neue Statistiken verfügbar
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
32 / 54
Embedded SQL
Embedded SQL in C/C++
Andere CLIs für Postgresql
Für C++: libpqxx
http://pqxx.org/
Für Ruby: pg
https://rubygems.org/gems/pg
require 'pg'
conn = PG::Connection.open(:host => 'localhost',
:dbname => 'university', :user => 'username',
:password => 'my password')
res = conn.exec("select name from studenten")
res.each do |row|
puts row['name']
end
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
33 / 54
Stored Procedures/UDFs
Stored Procedures / User-Defined Functions
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
34 / 54
Stored Procedures/UDFs
Stored Procedures/UDFs
Bislang: Kommunikation mit DBMS via Anwendungsprogrammen:
Einzelne Statements, Verarbeitung in Wirtssprache.
Manchmal ist es aber sinnvoll, Teile der Anwendung direkt im DBMS
auszuführen und nicht via einzelnen SQL Statements.
Vorteile
Daten müssen nicht erst auf dem DBMS zur Anwendung gebracht
werden (und umgekehrt)
Höhere Performanz
Code kann wiederverwendet werden (zwischen Anwendungen)
Nachteile
Etwas aufwendiger zu erstellen.
Debugging schwieriger.
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
35 / 54
Stored Procedures/UDFs
SQL vs. SQL/PSM vs. PL/SQL bzw. PL/pgSQL
SQL
Standard Query Language für Datenbanksysteme.
SQL Anweisungen können via Anwendungsprogrammierung (JDBC
oder Embedded SQL) an DB geschickt werden.
PSM
Persistent, Stored Modules (PSM)
Im SQL:2003 Standard definiert. Erlaubt es prozeduralen Code direkt
innerhalb der DB zu schreiben.
PL/SQL bzw. PL/pgSQL
Procedural Language/(PostgreSQL) Structured Query Language
Prozedurale Sprache, benutzt in Oracle bzw. Postgresql
PL/SQL bzw. PL/pgSQL erlauben diese Anwendungslogik als
Prozedur innerhalb des DBMS zu definieren.
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
36 / 54
Stored Procedures/UDFs
Vorteile von Stored Procedures / User Defined Functions
Ausführungspläne können vorübersetzt werden, sind wiederverwendbar
Anzahl der Zugriffe des Anwendungsprogramms auf das DBMS
werden reduziert
Prozeduren sind als gemeinsamer Code für verschiedene
Anwendungsprogramme nutzbar
Es wird ein höherer Isolationsgrad der Anwendung von dem DBMS
erreicht.
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
37 / 54
Stored Procedures/UDFs
Beispiel
CREATE FUNCTION g e t S t u d e n t ( m a t r n r i n t )
RETURNS i n t AS $$
DECLARE
qty i n t ;
BEGIN
SELECT COUNT( * ) INTO q t y
FROM s t u d e n t e n
WHERE s t u d e n t e n . m a t r n r = m a t r n r ;
RETURN q t y ;
END ;
$$ LANGUAGE p l p g s q l ;
select *
from getstudent(26120);
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
38 / 54
Stored Procedures/UDFs
Unterschied Stored Procedures und UDFs
Generel
UDF = user-defined function
Stored procedure muss explizit mit CALL aufgerufen werden (SQL
EXEC CALL name))
UDF kann direkt in SQL ohne CALL benutzt werden
In Postgresql
In Postgres (9.3) gibt es allerdings keinen Unterschied zwischen stored
procedures und UDFs
UDF wird aufgerufen in SELECT statements, z.b.
select from myFunction(44234234);
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
39 / 54
Stored Procedures/UDFs
UDFs in Postgresql
Verschiedene Arten von UDFs
Query language Funktionen (SQL)
Procedural language Funktionen (PL/pgSQL, Perl, ...)
Interne Funktionen
C Funktionen
PL/Java erlaubt auch die Nutzung von Java
(http://pgfoundry.org/projects/pljava/)
http://www.postgresql.org/docs/9.3/static/xfunc.html
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
40 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language (SQL) Funktionen
Mit Hilfe des Schlüsselworts LANGUAGE wird angegeben welche Sprache
zur Definition dieser Funktion benutzt wurde, hier SQL.
Diese Funktion hat den Rückgabewert void
Sie ist definiert als einfaches SQL delete Statement und besitzt auch
keine Eingabeparameter.
CREATE FUNCTION c l e a n e m p ( ) RETURNS
v o i d AS $$
DELETE FROM emp
WHERE s a l a r y < 0 ;
$$ LANGUAGE SQL ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
41 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language Funktionen (2)
Diese Funktion hat als Parameter ein Tupel der Relation emp, die
neben Name des Mitarbeiters, dessen Gehalt (Salary), Alter und
Raum (Als Point-Objekt) enthält.
Der Rückgabewert ist Typ numeric
INSERT INTO emp VALUES ( ' B i l l ' , 4 2 0 0 , 4 5 ,
'(2 ,1) ');
CREATE FUNCTION d o u b l e s a l a r y ( emp )
RETURNS n u m e r i c AS $$
SELECT $ 1 . s a l a r y * 2 AS s a l a r y ;
$$ LANGUAGE SQL ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
42 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language Funktionen (3)
CREATE FUNCTION addtoroom ( p r o f e s s o r e n )
RETURNS i n t AS $$
s e l e c t $ 1 . raum+1 ;
$$ LANGUAGE SQL
Anwendung/Aufruf:
select name, addtoroom(professoren.*) from professoren;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
43 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language Funktionen (4)
Hier wird eine Funktion definiert, die ein Dummy-Tupel für einen neuen
Professor erzeugt (gemäß der Relation professoren):
CREATE FUNCTION n e u e r P r o f ( )
RETURNS p r o f e s s o r e n
AS $$
SELECT 1 a s p e r s n r , t e x t ' Unbekannt ' AS name ,
t e x t ' C3 ' a s rang , 123 a s raum ;
$$ LANGUAGE SQL ;
Anwendung zum Beispiel:
insert into professoren (select * from neuerProf());
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
44 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language Funktionen (5)
Diese Funktion hat mehrere Eingaben und mehrere Ausgaben:
CREATE FUNCTION s u m n p r o d u c t
( x i n t , y i n t , OUT sum i n t , OUT p r o d u c t i n t )
AS $$ SELECT $ 1 + $ 2 , $ 1 * $ 2
$$ LANGUAGE SQL ;
Beispielaufruf:
SELECT * FROM sum_n_product(11,42);
sum | product
-----+--------53 |
462
(1 row)
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
45 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Query Language Funktionen (6)
Ruckgabewerte: Einzelne Zeilen vs. Tabellen
CREATE FUNCTION a l l e P r o f s ( )
RETURNS p r o f e s s o r e n
a s $$
s e l e c t * from p r o f e s s o r e n ;
$$ LANGUAGE SQL ;
Beispielaufruf:
select * from alleProfs();
persnr |
name
| rang | raum
--------+----------+------+-----2125 | Sokrates | C4
| 226
(1 row)
Was macht select alleProfs(); ?
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
46 / 54
Stored Procedures/UDFs
LANGUAGE SQL
Tabellen als Rückgabewerte: Table Functions
CREATE FUNCTION g e t P r o f s ( i n t )
RETURNS TABLE( p e r s n r i n t ) AS $$
SELECT p e r s n r from p r o f e s s o r e n p
WHERE p . p e r s n r < $ 1 ;
$$ LANGUAGE SQL ;
select * from getProfs(2130);
persnr
-------2125
2126
2127
(3 rows)
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
47 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL
Anstelle von SQL in den vorherigen Beispielen wird nun PL/pgSQL
betrachtet.
[ <<l a b e l >> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ l a b e l ] ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
48 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL
Anstelle von SQL in den vorherigen Beispielen wird nun PL/pgSQL
betrachtet.
CREATE FUNCTION s a l e s t a x ( s u b t o t a l r e a l )
RETURNS r e a l AS $$
BEGIN
RETURN s u b t o t a l * 0 . 0 6 ;
END ;
$$ LANGUAGE p l p g s q l ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
49 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL
CREATE FUNCTION
c o n c a t s e l e c t e d f i e l d s ( i n t sometablename )
RETURNS t e x t AS $$
BEGIN
RETURN i n t . f 1 | | i n t . f 3 | | i n t . f 5 | | i n t . f 7 ;
END ;
$$ LANGUAGE p l p g s q l ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
50 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL
Funktion mit zwei Eingabeparametern und zwei Ausgabeparametern:
CREATE FUNCTION
sum n product ( x int , y int ,
OUT sum i n t , OUT p r o d i n t )
AS $$
BEGIN
sum := x + y ;
p r o d := x * y ;
END ;
$$ LANGUAGE p l p g s q l ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
51 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL: SELECT INTO
SQL Anfragen, die nur eine Zeile zurück liefern können direkt in Variablen
eingelesen werden, z.B.
SELECT * INTO myrec FROM emp WHERE empname = myname ;
Falls mehrere Ergebnisse geliefert werden wird die erste Zeile benutzt.
Durch die Angabe von STRICT, also
SELECT * INTO STRICT myrec FROM emp
WHERE empname = myname ;
wird darauf geachtet, dass es nur genau ein Ergebnis gibt (ansonsten wird
eine Exception geworfen).
Siehe EXECUTE für dynamische Anfragen und PERFORM für Anfragen
ohne Eregebnis zu berücksitigen:
http://www.postgresql.org/docs/9.3/static/plpgsql-statements.html
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
52 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL: Kontrollstrukturen
PL/pgSQL bietet die übliche Auswahl and Kontrollstrukturen wie
IF-Statements und Schleifen (LOOP WHILE, FOR), EXIT (=break),
CONTINUE
LOOP
I F c o u n t > 0 THEN
EXIT ;
END I F ;
END LOOP ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
53 / 54
Stored Procedures/UDFs
LANGAGE PL/pgSQL
PL/pgSQL: Kontrollstrukturen und SQL Anfragen
Über Anfrageergebnisse iterieren
CREATE OR REPLACE FUNCTION t e s t i t ( ) RETURNS i n t a s
$$
DECLARE
m y p r o f s RECORD ;
myint i n t = 0 ;
BEGIN
FOR m y p r o f s i n SELECT * FROM p r o f e s s o r e n
WHERE p e r s n r <2130
LOOP
myint = myprofs . p e r s n r + myint ;
END LOOP ;
r e t u r n myint ;
END ;
$$ LANGUAGE p l p g s q l ;
Prof. Dr.-Ing. S. Michel
TU Kaiserslautern
Datenbankanwendung, WS 14/15
54 / 54