88
Jürgen Sieben Oracle PL/SQL Das umfassende Handbuch

Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Jürgen Sieben

Oracle PL/SQLDas umfassende Handbuch

1452.book Seite 1 Donnerstag, 5. August 2010 3:55 15

Page 2: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

3

Auf einen Blick

1 Einführung ........................................................................... 17

2 Verwendete Werkzeuge und Ressourcen .............................. 29

TEIL I Grundlagen ......................................................................... 53

3 Aufbau der Datenbank aus Sicht eines Programmierers ........ 55

4 Datensicherheit, -konsistenz und Transaktion ....................... 127

5 Die Datenbank in der Anwendungsarchitektur ..................... 181

6 Programmierung der Datenbank .......................................... 223

TEIL II Die Sprache PL/SQL .......................................................... 247

7 Die Blockstruktur und Syntax von PL/SQL ............................ 249

8 Events in der Datenbank: Programmierung von Triggern ...... 345

9 Das Arbeiten mit Daten ....................................................... 395

10 Packages .............................................................................. 441

11 Fehlerbehandlung ................................................................ 483

TEIL III PL/SQL im Einsatz ........................................................... 511

12 Erweiterung von SQL ........................................................... 513

13 Arbeiten mit großen Datenstrukturen ................................... 559

14 Arbeiten mit XML ................................................................ 603

15 Objektorientierung ............................................................... 681

16 Integration von Oracle in Applikationen ............................... 725

TEIL IV Workshops ...................................................................... 755

17 Workshop 1: Die Keimzelle sicherer Datenbankanwendungen ..................................................... 757

18 Workshop 2: Ein Logging-Package ........................................ 777

1452.book Seite 3 Donnerstag, 5. August 2010 3:55 15

Page 3: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

5

Inhalt

Die Oracle-Datenbank ist eines der mächtigsten und umfangreichsten relationalen Datenbanksysteme. Schon SQL ist ungeheuer vielseitig einsetzbar. Doch erst mit PL/SQL erschließt sich das gesamte Potenzial. Daher ist die Kenntnis von PL/SQL für jeden, der sich mit Oracle beschäftigt, essenziell. 17

1 Einführung .............................................................................. 17

1.1 Für wen ist dieses Buch geschrieben? ......................................... 171.2 Der Aufbau des Buches .............................................................. 21

1.2.1 Teil 1: Grundlagen ........................................................ 211.2.2 Teil 2: Die Sprache PL/SQL ............................................ 231.2.3 Teil 3: PL/SQL im Einsatz .............................................. 241.2.4 Teil 4: Workshops ......................................................... 26

1.3 Danksagung ............................................................................... 27

Damit wir uns im Folgenden auf die Themen konzentrieren können, erspare ich mir die dauernden Verweise auf die Online-Dokumentation oder die in diesem Buch verwendeten Werkzeuge. Stattdessen gebe ich Ihnen hier einen Überblick. 29

2 Verwendete Werkzeuge und Ressourcen .............................. 29

2.1 Oracles Online-Dokumentation ................................................. 292.1.1 Wo finde ich die benötigten Informationen? ................. 302.1.2 PL/SQL-Grundlagen ...................................................... 332.1.3 Oracle Packages ............................................................ 342.1.4 Weiterführende Literatur .............................................. 34

2.2 Aufsetzen einer Beispieldatenbank ............................................. 352.3 SQL*Plus ................................................................................... 382.4 SQL-Developer .......................................................................... 402.5 »explain plan« ............................................................................ 412.6 Autotrace .................................................................................. 432.7 RunStats .................................................................................... 452.8 Trace und TKProf ....................................................................... 462.9 DBMS_Profiler ........................................................................... 502.10 Debugger .................................................................................. 512.11 Die Beispielskripte ..................................................................... 52

TEIL I GrundlagenIn einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen und Arbeitsweisen für die Erstellung einer effizienten und skalierbaren Applikation kennen. 55

3 Aufbau der Datenbank aus Sicht eines Programmierers ....... 55

3.1 Instanz und Speicherstrukturen .................................................. 563.1.1 Die Speicherbereiche der SGA ....................................... 573.1.2 Shared Pool .................................................................. 593.1.3 Die Hintergrundprozesse ............................................... 60

3.2 Die physikalische Datenbank ..................................................... 653.2.1 Datendateien ................................................................ 65

1452.book Seite 5 Donnerstag, 5. August 2010 3:55 15

Page 4: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

6

3.2.2 Redo-Log-Dateien ......................................................... 663.2.3 Kontrolldatei ................................................................. 67

3.3 Parameter- und Passwortdatei ................................................... 673.3.1 Parameterdatei ............................................................. 673.3.2 Passwortdatei ............................................................... 68

3.4 Start der Datenbank .................................................................. 693.5 Verbindungsaufbau zur Datenbank ............................................ 70

3.5.1 Verbindungsarten und Treiber ....................................... 723.5.2 DEDICATED SERVER-Verbindung ................................. 783.5.3 Shared-Server-Verbindung ............................................ 793.5.4 Database Resident Connection Pool .............................. 813.5.5 Und nun? Entscheidungshilfen für den

Verbindungsaufbau ....................................................... 843.6 Logischer Aufbau: Schema, Tablespace & Co. ............................. 87

3.6.1 Schema ......................................................................... 883.6.2 Tablespace .................................................................... 933.6.3 Auswirkungen auf die Architektur einer Applikation....... 96

3.7 Datenbankobjekte ..................................................................... 993.7.1 Tabellen ........................................................................ 993.7.2 Index ............................................................................ 1053.7.3 Materialisierte Sichten .................................................. 1133.7.4 PL/SQL-Konstrukte ....................................................... 1153.7.5 Sonstige Datenbankobjekte ........................................... 115

3.8 Exkurs: Zeichensatzkodierung .................................................... 1203.8.1 Zeichensatzkodierung im Überblick ............................... 1203.8.2 Zeichensatzkodierung bei Oracle ................................... 122

Jedes Datenbankmanagementsystem ist anders implementiert. Obwohl viele Anwender hoffen , alle Datenbanken seien gleich und können als homogene Datenpumpen betrachtet werden, unterscheiden sie sich grundlegend und fundamental. Kaum ein Bereich der Implementierungsunterschiede ist so ausgeprägt und gleichzeitig so wichtig wie der Bereich der Datensicherheit,der Datenkonsistenz und der Transaktion. Dieses Kapitel befasst sich mit der Implementierung dieser Strategien in Oracle. 127

4 Datensicherheit, -konsistenz und Transaktion ...................... 127

4.1 Lese- und Schreibkonsistenz ...................................................... 1284.1.1 Lesekonsistenz .............................................................. 1284.1.2 Schreibkonsistenz .......................................................... 132

4.2 Transaktion ................................................................................ 1324.2.1 Transaktion zum Schutz der Lesekonsistenz ................... 1334.2.2 Transaktion zur Definition eines Geschäftsvorfalls........... 1354.2.3 Zusammenfassung ......................................................... 136

4.3 Datenkonsistenz und referenzielle Integrität .............................. 1374.3.1 Datenintegrität ............................................................. 1384.3.2 Performanzüberlegungen zu Datenbank-Constraints ...... 1434.3.3 Datenkonsistenz ........................................................... 1464.3.4 Zusammenfassung ......................................................... 150

1452.book Seite 6 Donnerstag, 5. August 2010 3:55 15

Page 5: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

7

4.4 Explizites Sperren von Daten durch die Anwendung .................. 1504.4.1 Das Problem: Lost Updates ........................................... 1514.4.2 Das optimistische Sperren ............................................. 1534.4.3 Das pessimistische Sperren ............................................ 1554.4.4 Do it the Oracle way: das vorsichtig optimistische

Sperren ......................................................................... 1564.4.5 Und nun? Wann sollte welche Sperrstrategie

verwendet werden? ...................................................... 1574.5 Verarbeitung einer SQL-Anweisung ........................................... 158

4.5.1 Parsen und Optimierung ............................................... 1594.5.2 Datenlieferung über Cursor ........................................... 164

4.6 Die Sperrmechanismen von Oracle ............................................ 1654.6.1 Locks ............................................................................ 1654.6.2 Latches ......................................................................... 166

4.7 Datensicherheit ......................................................................... 1664.8 Beispiel zum Einfluss der Programmierung ................................. 169

4.8.1 Das Ziel unserer Programmierung .................................. 1704.8.2 Implementierung des Tests ........................................... 171

Ist die Datenbank eine Datenpumpe? Viele Anwendungen betrachten die Datenbank lediglich als Lieferant für Daten, die von der Anwendung konsumiert werden, und als Speicher für die Anwendungsdaten. Zentrale Konzepte wie die Datenkonsistenz oder die Datensicherheit gehen bei diesem Ansatz verloren, ebenso wie der Großteil der ansonsten möglichen Performanz.Sehen wir uns also die Datenbank im Kontext der Anwendung genauer an. 181

5 Die Datenbank in der Anwendungsarchitektur ..................... 181

5.1 Das Problem des Impedance Mismatch ..................................... 1835.1.1 Das Problem der Identität ............................................. 1835.1.2 Das Problem der Datensuche ........................................ 1845.1.3 Das Problem der Lesestrategie ...................................... 1865.1.4 Das Problem der Vererbung .......................................... 1885.1.5 Das Problem der Kopplung von Logik und Daten ........... 1915.1.6 Das Problem der referenziellen Integrität ...................... 192

5.2 Lösungsansatz 1: Die Vision der generischen Datenbank ............ 1935.2.1 Generisches SQL ........................................................... 1935.2.2 Generisches Abfragewerkzeug ....................................... 1975.2.3 Die Kosten generischer Datenbankprogrammierung....... 198

5.3 Lösungsansatz 2: Objektrelationale Mappingwerkzeuge ............. 2005.3.1 Abbildung der Objekte auf Tabellen .............................. 2005.3.2 Kapselung der SQL-Dialekte .......................................... 2015.3.3 Caching-Mechanismen, Lazy Load ................................. 2015.3.4 Transaktionsverwaltung ................................................. 2015.3.5 Zusammenfassung ......................................................... 202

5.4 Lösungsansatz 3: Die Datenbank als Datenframework ................ 2035.4.1 Performanz der Datenbearbeitung ................................ 2045.4.2 Sicherheitsdomäne ........................................................ 2055.4.3 Integration von PL/SQL und SQL ................................... 208

1452.book Seite 7 Donnerstag, 5. August 2010 3:55 15

Page 6: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

8

5.5 Mächtigkeit von SQL ................................................................. 2095.5.1 Analytische Funktionen ................................................. 2105.5.2 Hierarchische Abfragen ................................................. 2125.5.3 Error Logging ................................................................ 2165.5.4 Fazit .............................................................................. 221

Die Oracle-Datenbank kann von PL/SQL-Programmen in vielerlei Bereichen profitieren. Bevor wir uns der Sprache und ihrer Syntax zuwenden, sehen wir uns an, für welche Einsatzszenarien PL/SQL normalerweise verwendet wird. 223

6 Programmierung der Datenbank ........................................... 223

6.1 Erweiterung der Datenbankfunktionalität .................................. 2236.2 Programmierung der Datenkonsistenz ....................................... 225

6.2.1 Datenbanktrigger .......................................................... 2256.2.2 Datenzugriff über PL/SQL .............................................. 2296.2.3 Datenkonsistenz jenseits referenzieller Integrität ............ 232

6.3 Programmierung der Datensicherheit ......................................... 2336.4 Anwendungsprogrammierung mit PL/SQL ................................. 236

6.4.1 PL/SQL auf der Clientseite ............................................. 2376.4.2 Webanwendungen mit PL/SQL entwickeln .................... 238

6.5 Unterstützung der Administration durch PL/SQL ........................ 2426.5.1 Einsatz von PL/SQL in Skripten ...................................... 2436.5.2 Verwaltung wiederkehrender Aufgaben mit Scheduler

und Jobs ....................................................................... 2446.5.3 Datenbanktrigger im Umfeld der Datensicherung

und des Auditings ......................................................... 245

TEIL II Die Sprache PL/SQLGenug der Vorbereitung: Nun geht es an die Definition der Sprache PL/SQL und an die Strukturen, die Sie kennen müssen, um eigene Programme entwerfen zu können. Dieses Kapitel führt zunächst in die grundlegenden Strukturen ein. Sie lernen die Blockstruktur sowie die wichtigsten Anweisungen von PL/SQL kennen. 249

7 Die Blockstruktur und Syntax von PL/SQL ............................ 249

7.1 Vom anonymen Block zum Package ........................................... 2507.1.1 Das Grundgerüst: Der PL/SQL-Block ............................. 2507.1.2 Prozeduren ................................................................... 2567.1.3 Funktionen ................................................................... 2667.1.4 Datenbanktrigger .......................................................... 2697.1.5 Packages ....................................................................... 2727.1.6 Ausführungsrechte von PL/SQL-Blöcken

(AUTHID-Klausel) ......................................................... 2767.1.7 Kompileranweisungen (PRAGMA-Klausel) .................... 2797.1.8 Best Practices ............................................................... 281

7.2 PL/SQL-Datentypen ................................................................... 2827.2.1 SQL-Datentypen ........................................................... 2827.2.2 Basistypen und Subtypen in PL/SQL .............................. 284

1452.book Seite 8 Donnerstag, 5. August 2010 3:55 15

Page 7: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

9

7.2.3 SQL-Datentypen mit abweichender Definition in PL/SQL ...................................................................... 286

7.2.4 SQL-Datentypen, die in PL/SQL nicht existieren............. 2877.2.5 PL/SQL-Datentypen, die in SQL nicht existieren............. 2877.2.6 Benutzerdefinierte Datentypen ..................................... 2887.2.7 Ableitung von Variablentypen aus dem Data

Dictionary ..................................................................... 2887.3 Kontrollstrukturen ..................................................................... 291

7.3.1 Bedingte Anweisung 1 (IF-THEN-ELSE-Anweisung) ........ 2917.3.2 Bedingte Anweisung 2 (CASE-Anweisung) ..................... 2927.3.3 Konditionale Kompilierung ........................................... 2957.3.4 Einfache Schleifen (LOOP-Anweisung) .......................... 3007.3.5 Abweisende Schleife 1 (FOR-LOOP-Anweisung) ............ 3017.3.6 Abweisende Schleife 2 (WHILE-LOOP-Anweisung) ....... 3037.3.7 Best Practices ................................................................ 3047.3.8 Aus der Mottenkiste: Konzepte, die Sie nicht

verwenden sollten ......................................................... 3077.4 Kollektionen in PL/SQL .............................................................. 310

7.4.1 Record .......................................................................... 3107.4.2 Assoziative Tabellen ...................................................... 3147.4.3 Cursor ........................................................................... 316

7.5 Dynamisches SQL ...................................................................... 3247.5.1 Natives dynamisches SQL

(Execute-Immediate-Anweisung) ................................... 3257.5.2 Dynamisches SQL mit Cursorvariablen ........................... 3287.5.3 DBMS_SQL-Package ..................................................... 3307.5.4 Sicherheit bei dynamischem SQL ................................... 333

7.6 Objektorientierte Datentypen .................................................... 3377.6.1 VARRAY ....................................................................... 3377.6.2 Geschachtelte Tabellen (nested tables) .......................... 341

Triggerprogrammierung ist ein komplexes, manchmal etwas hakeliges Thema. Neben den unbestreitbaren Vorteilen von Triggern lauern einige logische Stolperfallen sowie da und dort einige nicht ganz intuitive Einschränkungen. Grund genug, Trigger einmal etwas genauer anzusehen. 345

8 Events in der Datenbank: Programmierung von Triggern ..... 345

8.1 DML-Trigger .............................................................................. 3458.1.1 Anweisungs- versus Zeilentrigger .................................. 3478.1.2 Wann wird ein Trigger ausgelöst? .................................. 3518.1.3 Das Mutating-Table-Problem ........................................ 3538.1.4 Compound-Trigger ........................................................ 3558.1.5 Instead-Of-Trigger ........................................................ 357

8.2 Datenbank-Trigger ..................................................................... 3598.2.1 Ereignisattribute ............................................................ 360

1452.book Seite 9 Donnerstag, 5. August 2010 3:55 15

Page 8: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

10

8.2.2 Datenbankereignisse ..................................................... 3628.2.3 Benutzerbezogene Ereignisse ........................................ 364

8.3 Einsatzbereiche von Triggern ..................................................... 3678.3.1 Datenintegrität durchsetzen .......................................... 3678.3.2 DML-Ereignisse, die von Triggern überwacht werden..... 3698.3.3 Auditierung mithilfe von Triggern .................................. 3758.3.4 Historisierung von Daten ............................................... 3778.3.5 Trigger und Datensichten (INSTEAD-OF-Trigger)............ 3818.3.6 DDL-Ereignisse ............................................................. 3898.3.7 System-Ereignisse .......................................................... 391

8.4 Zusammenfassung ..................................................................... 391

Die zentrale Aufgabenstellung für die Programmierung von PL/SQL ist der Umgang mit den Daten der Datenbank. PL/SQL ist für diese Aufgabe besser gerüstet als jede andere Programmiersprache im Oracle-Umfeld, denn als Erweiterung zu SQL setzt sie direkt auf der Datenbanksprache auf. Grund genug, diese Vorteile zu nutzen! 395

9 Das Arbeiten mit Daten ......................................................... 395

9.1 Strukturierte Variablen: Records und Typen ............................... 3959.1.1 Bindung an das Data Dictionary mit »%TYPE« und

»%ROWTYPE« .............................................................. 3959.1.2 Insert- und Update-Anweisungen mit Records ............... 3989.1.3 Verwendung explizit deklarierter Records ..................... 4019.1.4 Verwendung der Returning-Klausel mit Records ............ 4049.1.5 Alternative zum Record: Objekt .................................... 406

9.2 PL/SQL-Kollektionen ................................................................. 4079.2.1 Verwendung von assoziativen Tabellen ......................... 4079.2.2 Massenverarbeitung mit assoziativen Tabellen ............... 4099.2.3 Tabellenfunktionen (PIPELINED-Functions) ................... 415

9.3 Mengenverarbeitung mit Cursorn .............................................. 4239.3.1 Implizite versus explizite Cursor .................................... 4239.3.2 Top-N-Analyse .............................................................. 4299.3.3 Cursorvariablen (REF-Cursor) ......................................... 4329.3.4 Cursor-Ausdrücke ......................................................... 435

PL/SQL-Code wird in Packages organisiert. Doch über das reine Organisieren von Code hinaus bieten Packages einen erheblichen Mehrwert, der die Programmierung in PL/SQL erst zu ihrer vollen Leistungsfähigkeit führt. Dieses Kapitel beleuchtet Strategien und Möglichkeiten des Einsatzes von Packages und wirft einen Blick auf die mitgelieferten Packages von Oracle. 441

10 Packages ................................................................................. 441

10.1 Warum sollten Packages genutzt werden? ................................. 44110.1.1 Trennung von öffentlicher und privater Logik ................ 44210.1.2 Überladung in Packages ................................................ 45210.1.3 Packages und die Abhängigkeitskette ............................ 45810.1.4 Verschlüsselung von Package-Code ............................... 464

10.2 Oracle-Packages ........................................................................ 47010.2.1 Das Package »standard« ................................................ 47310.2.2 Wichtige Oracle-Packages ............................................. 474

1452.book Seite 10 Donnerstag, 5. August 2010 3:55 15

Page 9: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

11

Die Fehlerbehandlung ist ein zentraler, aber nicht eben beliebter Teil jeder Programmiersprache. Wir beschäftigen uns selbstverständlich dennoch mit der Fehlerbehandlung und zeigen die Möglichkeiten der Sprache PL/SQL auf. 483

11 Fehlerbehandlung ................................................................... 483

11.1 Oracle-Fehler ............................................................................. 48311.1.1 Benannte Fehler ............................................................ 48911.1.2 »SQLERRM« und »SQLCODE«-Funktionen und der

Fehlerstack .................................................................... 49111.1.3 Nicht benannte Fehler benennen .................................. 494

11.2 Applikationsfehler erstellen und bearbeiten ............................... 49511.2.1 Fehler direkt mit RAISE_APPLICATION_ERROR

erzeugen ....................................................................... 49511.2.2 Fehler aus einem Fehlerpackage erstellen lassen............. 49611.2.3 Zentralisierung der Fehlermeldungen über »LMSGEN«..... 498

11.3 Zentralisierter Fehlerhandler mit einem Trigger .......................... 50511.4 Zusammenfassung ..................................................................... 510

TEIL III PL/SQL im EinsatzDie Erweiterung von SQL ist das natürliche Anwendungsgebiet von PL/SQL. Wir überlegen, wann eine Erweiterung durch PL/SQL sinnvoll ist und welcher Preis dafür gezahlt werden muss, und wir schrecken auch vor fortgeschrittenen Themen nicht zurück. 513

12 Erweiterung von SQL ............................................................. 513

12.1 Wann SQL erweitert werden sollte ............................................ 51312.1.1 Bleiben Sie auf dem aktuellen Wissensstand! ................ 51412.1.2 Voraussetzungen für die Erweiterung von SQL ............... 517

12.2 SQL mit eigenen Funktionen erweitern ...................................... 51912.2.1 Anforderungen an den PL/SQL-Block ............................ 51912.2.2 Nebenwirkungsfreiheit (Purity) ...................................... 52012.2.3 Optimizer Hints ............................................................ 52012.2.4 Das Pragma »restrict_references« .................................. 52112.2.5 Beispielfunktion ............................................................ 522

12.3 Code-Beispiel: Berechnung der Fakultät ..................................... 52812.4 Gruppenfunktionen selbst erstellen ........................................... 538

12.4.1 Arbeitsweise von Gruppenfunktionen ........................... 53912.4.2 Beispiel ......................................................................... 54212.4.3 Test der Gruppenfunktion ............................................. 54712.4.4 Zusammenfassung ......................................................... 548

12.5 Code-Beispiel: Codegenerator für Gruppenfunktionen ............... 549

Oracle unterstützt die Speicherung und Bearbeitung von großen Binär- und Textdateien. Die Arbeit mit diesen Datentypen hat sich zwar der Verarbeitung normaler Zeichenketten oder Raw-Daten angeglichen, doch gibt es immer noch Unterschiede, die beachtet werden müssen. Dieses Kapitel führt in die Bearbeitung dieser Datenstrukturen ein. 559

13 Arbeiten mit großen Datenstrukturen ................................... 559

13.1 Technische Struktur ................................................................... 56013.1.1 Einsatz von LOB-Datentypen in der Datenbank.............. 56013.1.2 LOBs als PL/SQL-Variablen ............................................ 565

1452.book Seite 11 Donnerstag, 5. August 2010 3:55 15

Page 10: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

12

13.1.3 LOBs als Methodenparameter ....................................... 57113.1.4 Secure Files ................................................................... 572

13.2 Die Datentypen CLOB, NCLOB, BLOB und BFILE ....................... 57513.2.1 CLOB und NCLOB ......................................................... 57513.2.2 Der binäre Datentyp BLOB ............................................ 57613.2.3 BFILE ............................................................................ 576

13.3 Das Package DBMS_LOB ........................................................... 57813.3.1 Schreibzugriff auf temporäre oder persistente LOBs ....... 57913.3.2 Verwaltung temporärer und persistenter LOBs ............... 58113.3.3 API für Bfile-LOBs ......................................................... 583

13.4 Hilfsfunktionen zum Arbeiten mit LOBs ..................................... 58413.4.1 Hilfsfunktion zum Laden von CLOBs und BLOBs aus

dem Dateisystem in die Datenbank ............................... 58413.4.2 Hilfsfunktion zum Lesen von CLOBs und BLOBs aus

der Datenbank .............................................................. 592

XML ist eine Kerntechnologie zur Übermittlung von Daten zwischen Systemen, zur Speicherung umfangreicher Dokumente und als Bindeglied zwischen objektorientierter und relationaler Datenhaltung und -verarbeitung. Dieses Kapitel beleuchtet die umfangreiche Unterstützung des Standards durch die verschiedenen Oracle-Technologien. 603

14 Arbeiten mit XML ................................................................... 603

14.1 Der Datentyp »XMLType« .......................................................... 60614.1.1 Verwendung von »XMLType« als Tabellen- oder

Spaltentyp .................................................................... 60614.1.2 »XMLType«-Methoden ................................................. 611

14.2 Die Speicherung von XML-Daten in der Datenbank ................... 61314.3 XML aus relationalen Daten erzeugen ........................................ 615

14.3.1 Der SQL/XML-Standard ................................................ 61514.3.2 Das Package »dbms_xmlgen« ........................................ 621

14.4 Relationale Daten aus XML extrahieren ..................................... 63114.5 XML mit PL/SQL verarbeiten ..................................................... 638

14.5.1 Die Programmierung von XML ...................................... 63814.5.2 Die XML-Packages ........................................................ 640

14.6 Die XML-Datenbank .................................................................. 65114.6.1 Einführung in die XML-Datenbank ................................ 65214.6.2 Speicherung und Veröffentlichung binärer und

XML-Dokumente .......................................................... 65414.6.3 Dokumente über XDB verwalten ................................... 65914.6.4 Zugriffsschutz und Sicherheit der XDB ........................... 67014.6.5 Versionierung von Ressourcen ...................................... 676

1452.book Seite 12 Donnerstag, 5. August 2010 3:55 15

Page 11: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

13

Kaum eine Funktionalität der Oracle-Datenbank hat so kontroverse Diskussionen ausgelöst wie die Integration objektorientierter Techniken. In diesem Kapitel zeige ich die Vor- und Nachteile dieser Techniken auf und stelle Ihnen sinnvolle Einsatzgebiete vor. 681

15 Objektorientierung ................................................................ 681

15.1 Einführung in die Objektorientierung ......................................... 68315.1.1 Alles ist ein Objekt ........................................................ 68415.1.2 Das zweite Reizwort: Vererbung! .................................. 68615.1.3 Abstrakte und finale Klassen ......................................... 68715.1.4 Statische Methoden ...................................................... 68815.1.5 Objektidentität versus »Statement of Truth« .................. 68915.1.6 Klassen haben komplexe Strukturen .............................. 69115.1.7 Auswirkungen auf die Datenbankprogrammierung ......... 693

15.2 Typen ........................................................................................ 69515.3 Anwendungsbeispiel: Der Datentyp »MoneyType« .................... 697

15.3.1 Vorüberlegungen .......................................................... 69715.3.2 Implementierung des »MoneyType« .............................. 69915.3.3 Der Typkörper ............................................................... 70115.3.4 Implementierung des Packages »coa_money« ................ 70515.3.5 Der Package-Körper ...................................................... 70715.3.6 Die Rechtesituation in Version 11g ............................... 71815.3.7 Erweiterung durch Vererbung ....................................... 721

15.4 Best Practices ............................................................................ 723

Dieses Kapitel beschäftigt sich mit der Integration von Oracle-Datenbanken in Anwendungen. Es wird uns hauptsächlich um strategische Fragen gehen, wie etwa die, welche Aufgaben wo erledigt werden sollten. Aber auch Techniken zur Integration kommen nicht zu kurz. 725

16 Integration von Oracle in Applikationen ............................... 725

16.1 Sperrung von Daten bei der Datenänderung .............................. 72616.1.1 Pessimistisches Locking ................................................. 72716.1.2 Optimistisches Locking ................................................. 73316.1.3 Database-Change-Notification-basiertes Locking............ 741

16.2 Zugriff auf Daten über PL/SQL-Packages .................................... 74316.2.1 Kapselung von DML-Operationen in Packages ............... 74416.2.2 Vermeidung von Triggern durch Packages ..................... 74516.2.3 Integration datenbezogener Geschäftsregeln ................. 746

16.3 Zugriff auf Daten über das Web ................................................. 74816.3.1 Veröffentlichung von Packages über HTTP .................... 74916.3.2 Schreiben von Daten in einen HTTP-Stream .................. 74916.3.3 Webservices aus PL/SQL ............................................... 750

16.4 Gemeinsamer Zugriff auf Daten über verteilte Cursor ................. 75116.4.1 Prozeduren mit »REF_CURSOR«-Parametern ................. 75116.4.2 Arbeit mit LOBs ............................................................ 752

16.5 Zusammenfassung und Bewertung ............................................. 753

1452.book Seite 13 Donnerstag, 5. August 2010 3:55 15

Page 12: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

14

TEIL IV WorkshopsIn diesem Workshop stelle ich Ihnen eine praktische Umsetzung der Empfehlungen vor, die ich Ihnen bezüglich der Nutzung der Datenbank als Datenframework gegeben habe. Wir werden eine Grundlage erarbeiten, die Sie als Keimzelle eigener Datenbankanwendungen verwenden können. 757

17 Workshop 1: Die Keimzelle sicherer Datenbankanwendungen ....................................................... 757

17.1 Das Projekt ................................................................................ 75717.1.1 Übersicht über die Architektur ...................................... 75817.1.2 Die Logon-Prozedur ...................................................... 761

17.2 Aufsetzen der Schemata ............................................................ 76217.3 Die Packages ............................................................................. 76617.4 Test der Architektur ................................................................... 77217.5 Zusammenfassung und Ausblick ................................................. 774

Zum Abschluss des Buches möchte ich mit Ihnen nun ein größeres Projekt besprechen, das für Ihre Projekte vielleicht wiederverwendbar ist. Es handelt sich um ein Package zum Logging und zur Fehlerbehandlung. 777

18 Workshop 2: Ein Logging-Package ........................................ 777

18.1 Überblick: Die Idee und die Architektur ..................................... 77818.1.1 Meldung ....................................................................... 78018.1.2 Kontext ......................................................................... 78118.1.3 Ausgabemodule ............................................................ 78218.1.4 Parameter- und Meldungstabelle .................................. 78418.1.5 Meldungspackage ......................................................... 789

18.2 Umsetzung des Logging-Packages .............................................. 79018.2.1 Die Parametertabelle .................................................... 79018.2.2 Die Meldungstabelle ..................................................... 79118.2.3 Das Meldungsobjekt ..................................................... 79418.2.4 Das Grundmodul ........................................................... 80018.2.5 Kontext ......................................................................... 80818.2.6 Parameterliste ............................................................... 809

18.3 Implementierung des Logging-Packages .................................... 81118.3.1 Die Package-Spezifikation des Logging-Packages............ 81118.3.2 Der Package-Körper des Logging-Packages ................... 81418.3.3 Test des Logging-Packages ............................................ 827

18.4 Implementierung des Log-Administrations-Packages ................. 82818.4.1 Funktionsüberblick und Implementierungsstrategie........ 82818.4.2 Implementierung der Log-Administration-Package-

Spezifikation ................................................................. 83018.4.3 Implementierung des Log-Administration-

Package-Körpers ........................................................... 83218.5 Weitere Ausgabemodule ........................................................... 846

18.5.1 Ausgabe in eigene Fehlerdateien ................................... 84718.5.2 Ausgabe in Alert-Log- oder Trace-Dateien .................... 855

1452.book Seite 14 Donnerstag, 5. August 2010 3:55 15

Page 13: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

Inhalt

15

18.5.3 Ausgabe in Logging-Tabellen ........................................ 85618.5.4 Meldung als E-Mail versenden ...................................... 85718.5.5 Meldungen in JMS integrieren ...................................... 859

Index .......................................................................................................... 865

1452.book Seite 15 Donnerstag, 5. August 2010 3:55 15

Page 14: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

17

Die Oracle-Datenbank ist eines der mächtigsten und umfangreichsten relationalen Datenbanksysteme. Schon SQL ist ungeheuer vielseitig ein-setzbar. Doch erst mit PL/SQL erschließt sich das gesamte Potenzial. Daher ist die Kenntnis von PL/SQL für jeden, der sich mit Oracle beschäftigt, essenziell.

1 Einführung

PL/SQL ist keine Programmiersprache.

Das mag zunächst verwunderlich klingen, schließlich bedeutet PL/SQL Procedu-ral Language for SQL, also eben das Gegenteil des Einleitungssatzes. Doch schonim ersten Satz von Oracle zur Einführung in PL/SQL heißt es: PL/SQL ist eine pro-zedurale Erweiterung von SQL. Dieser feine Unterschied ist sehr wichtig, auch fürdieses Buch: Ein Buch über PL/SQL ist nicht komplett ohne ein Buch über SQL.Sollten Sie also ein Neueinsteiger in die Welt der Oracle-Datenbanken sein, sollteIhr erstes Augenmerk auf der Abfragesprache SQL liegen, nicht auf PL/SQL. Diesyntaktischen Grundlagen von PL/SQL, die Namenskonventionen, aber auch dieüberwältigende Mehrheit der Funktionen in PL/SQL kommen aus SQL. Das vor-weggenommen, ist PL/SQL aber auch eine faszinierende Technologie, mit derenHilfe Sie der Datenbank die mächtige Funktionalität abgewinnen können, die Siesonst nur in sehr wenigen, anderen Datenbanken finden. Mit diesem Buchmöchte ich Sie in die Sprache PL/SQL einführen und Ihnen erläutern, wie Sie ausder Datenbank maximalen Nutzen für Ihre Anwendung ziehen können.

1.1 Für wen ist dieses Buch geschrieben?

Nun, ganz eindeutig für Sie. Damit meine ich, dass die Konzeption dieses Buchesnatürlich kein Selbstzweck, sondern dem Ziel unterworfen ist, Ihnen zu erklären,wie und wofür PL/SQL einzusetzen ist, und eben nicht dem Ziel, einfach nur einBuch über PL/SQL zu schreiben, das lediglich alle wichtigen Merkmale der Spra-che auflistet. Daher habe ich mir zu Beginn Gedanken darüber gemacht, wer Sieeigentlich sind. Wer liest ein solches Buch? Ich stelle mir vor, dass Sie beruflichbereits mit Datenbanken zu tun hatten, auch schon programmiert haben und nunIhre Kenntnisse und Fähigkeiten um PL/SQL erweitern möchten oder müssen.

1452.book Seite 17 Donnerstag, 5. August 2010 3:55 15

Page 15: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

18

Einführung1

Vielleicht sind Sie ein Administrator, der sich in die Programmierung von Trig-gern einarbeiten oder PL/SQL-Programme zur Erleichterung seiner Arbeit verfas-sen muss? Vielleicht sind Sie aber auch ein Anwendungsentwickler, der bislangin einer der Programmiersprachen für Anwendungsentwicklung programmierthat und nun, freiwillig oder aufgrund von Performanzproblemen gezwungen,einen näheren Blick in die Datenbankinterna werfen will? Vielleicht sind Sie derBetreuer einer Software, die von anderen geschrieben wurde (vielleicht von Vor-gängern im Amt) und Ihnen nun zur weiteren Betreuung überlassen wurde. SindSie ein absoluter Neuling in Datenbanken und wollen den Einstieg über PL/SQLerreichen? Nein, das glaube ich eigentlich nicht. Daher richte ich mein Buch anmeiner Erwartung an Sie aus.

Dieses Buch richtet sich einerseits an Leser, die SQL-Kenntnisse haben. PL/SQL-Bücher sind keine Einstiegsliteratur in Datenbanken, sondern setzen den Wegfort, den Sie durch die Auseinandersetzung mit relationalen Datenmodellen undSQL bereits begonnen haben. Ich setze nicht voraus, dass Ihre SQL-Kenntnissesehr tiefgehend sind, doch ein Grundverständnis dieser Abfragesprache sollte injedem Fall vorhanden sein. Dann gehe ich davon aus, dass Sie bereits in irgend-einer Programmiersprache programmiert haben. Ich kann mir einfach nicht rechtvorstellen, dass Sie das Programmieren gerade innerhalb einer Datenbank lernenmöchten (oder müssen). Normalerweise, das lehrt mich auch die Erfahrung ausden vielen Kursen, die ich zum Thema PL/SQL-Einführung gegeben habe, ist dieProgrammierung der Datenbank ein Thema für Menschen, die bereits Program-miererfahrung in anderen Sprachen, sei es Cobol, C, C++, Java oder VisualBasic,haben. Daher möchte ich Sie nicht langweilen und erläutere die Grundlageneiner If-Anweisung nur sehr kurz.

Sollten Sie eine der beiden Voraussetzungen, die ich hier genannt habe, nichtmitbringen, empfehle ich Ihnen, sich zunächst mit diesen Themen zu beschäfti-gen. Insbesondere gilt diese Empfehlung für die Beschäftigung mit der Abfra-gesprache SQL. Je besser Sie diese Sprache beherrschen, umso leichter fällt esIhnen, Aufgabenstellungen in Bezug auf Daten einer Datenbank zu lösen. Undauch das gilt: Je besser Sie SQL beherrschen, umso seltener müssen Sie zu einerProgrammiersprache greifen, um ein Problem zu lösen. Das ist leider auch aufder Zeitachse wahr: Sollten Sie sich sehr gut mit dem SQL der Oracle-Datenbank-version 7.3.4 auskennen, werden Sie staunen, was seit dieser Zeit in SQL anFähigkeiten hinzugekommen ist. Die Beschäftigung mit SQL ist immer dieBeschäftigung mit SQL in der Datenbankversion Ihrer Datenbank. Für diejenigenunter Ihnen, die noch nicht programmiert haben, glaube ich, wird der Stoff rela-tiv schnell und wenig didaktisch vorangehen. Vielleicht sollten Sie ins Auge fas-sen, die Programmierung vorab zu erlernen. Auch hier geht es weniger darum,

1452.book Seite 18 Donnerstag, 5. August 2010 3:55 15

Page 16: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

19

Für wen ist dieses Buch geschrieben? 1.1

Experte in einer Programmiersprache zu sein, sondern um ein generelles Ver-ständnis der Vorgehensweise beim Programmieren. Diese Einführung kann die-ses Buch nicht leisten.

Darüber hinaus muss ich eine – für mich sehr schwierige – Entscheidung treffen:Werden Sie als meine Leser eher Entwickler sein, Endanwender oder Adminis-tratoren? Welcher konkrete Einsatzzweck liegt Ihrem Interesse an PL/SQLzugrunde? Diese Entscheidung ist nicht leicht. Ich habe mich dafür entschieden,aus dem Blickwinkel des Entwicklers und des Administrators zu schauen; derSchwerpunkt liegt allerdings auf dem Blickwinkel des Entwicklers von Anwen-dungssoftware. Aus dieser Entscheidung resultieren mehrere Konsequenzen:

� Ich gehe davon aus, dass die meisten Anwendungsentwicklungen (insbeson-dere neu aufgesetzte Projekte) nicht mehr nur in einer Technologie allein ent-wickelt werden. Die aktuellen Architekturentscheidungen mit Webanwen-dungen, Applikationsservern und Datenbankservern lassen eine Entwicklungin einer Programmiersprache eigentlich auch nicht zu. Daher widme ich eini-gen Raum dieses Buches auch den Problemen der Integration von Oracle-Datenbanken in Anwendungen, die in anderen Programmiersprachen entwi-ckelt werden.

� Ich gehe weiterhin davon aus, dass Datenbanken (nicht nur Oracle, sondernDatenbanken generell) vielen Anwendungsentwicklern nur als Datenspeichergeläufig sind und die Interna der Arbeitsweise ihnen nicht immer komplettbekannt sind. Daher gebe ich eine ausführliche Einführung in die Arbeits-weise von Oracle-Datenbanken. Diese Einführung wird für Administratorenbekannt und eventuell etwas oberflächlich sein, ist aus meiner Sicht für Ent-wickler aber unbedingt von Interesse, um zu verstehen, warum die Daten-bank auf eine gewisse Weise programmiert werden will. Für Administratorenschließlich sind Kenntnisse einiger Aspekte der Anwendungsprogrammierungvon unschätzbarem Wert, einfach, um zu verstehen, welche Problemstellun-gen durch Anwendungsentwickler in der Datenbank gelöst werden müssen.Daher empfehle ich die Abschnitte, die sich mit der Entwicklung von Anwen-dungen und der Integration von Oracle-Datenbanken in solche Anwendungenbefassen, auch den Administratoren.

� Ich gehe schließlich davon aus, dass es wichtiger ist, zu erklären, warum etwasgetan werden muss, als wie etwas getan werden muss. Anders gesagt: DiesesBuch ist keine Referenz zu PL/SQL, in der Sie im Index einen Befehl nachschla-gen können und auf Seite 371 alle Parameter der Prozedur aufgelistet bekom-men. Diese Funktion übernehmen die Online-Ressourcen, die bei Oracle aufeinem sehr hohen Niveau sind, wesentlich besser. Allein die Dokumentation

1452.book Seite 19 Donnerstag, 5. August 2010 3:55 15

Page 17: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

20

Einführung1

der mitgelieferten Packages umfasst bei der Datenbankversion 11gR2 stolze5.744 Seiten … Nebenbei sind das über 600 Seiten mehr als zu Datenbankver-sion 11gR1, und das bringt mich zum ersten Grund für meine Entscheidung,keine Referenz zu PL/SQL zu schreiben: Diese ist naturgemäß von der Versionder Datenbank abhängig und daher schon veraltet, bevor sie ausgeliefert wird.Der zweite Grund ist, dass es mir ein besonderes Anliegen ist, Ihnen zu erklä-ren, wie die Datenbank gut programmiert wird. Die Kunst besteht darin, derDatenbank bei der Erfüllung ihrer Aufgaben möglichst nicht im Wege zu ste-hen. Das ist gar nicht so leicht und gelingt nur, wenn Sie wissen, was Sie tun.Und genau dafür benötige ich Platz, den ich nicht durch Auflistungen von Pro-zedurparametern verschwenden wollte. Ich trete mit dem Ziel an, Ihnen zuerklären, was Sie tun müssen und warum, um eine gute Anwendung oderAnwendungsunterstützung zu erhalten. Messen Sie mich daran.

Außerdem ist dies ein Buch, in dem ich meine Meinung kund tue. Vielleichtsollte ich so etwas nicht tun, und vielleicht reizt dies zum Widerspruch. Ich habemich dennoch entschieden, meine persönliche Meinung darüber mitzuteilen,wie eine Datenbank, speziell eine Oracle-Datenbank, programmiert werdensollte. Die Meinung basiert auf meiner Berufserfahrung, in der ich viel Code gese-hen habe. Aufgrund meines Berufes komme ich vor allem zu Kunden, derenCode nicht oder nicht gut genug läuft. Daher sehe ich viel Code so, wie er nichtgeschrieben werden sollte. Meine Meinung reflektiert dabei die Erfahrungen, dieich in diesen Projekten gesammelt habe, aber natürlich auch den Input, den ichvon vielen sehr guten Kollegen und Autoren eingesogen habe. Trotzdem mögenSie über die Ausrichtung von Software anderer Meinung sein als ich. Vielleichtarbeiten Sie in einem Team aus erfahrenen PL/SQL-Entwicklern, die Ihnen sagen,dass das, was ich hier schreibe, gut und schön, im konkreten Unternehmensum-feld aber nicht umsetzbar sei. Ich bin weit davon entfernt, hier Einspruch anzu-melden. Natürlich gibt es viele, gute Gründe für eine Position. Es gibt auch vielerichtige Positionen. Allerdings gibt es noch mehr falsche Positionen. Gerade amAnfang ist es aber schwer, falsche von richtigen Positionen zu unterscheiden. Dajedoch gerade am Anfang eines Projekts Entscheidungen zugunsten oder zuun-gunsten einer Strategie fallen, die später nur schwer korrigierbar sind, empfindeich es als richtig, auch in einem Einführungsbuch bereits eine richtige Position zubeziehen und Sie nicht mit dieser Einschätzung allein zu lassen. Sind Sie andererMeinung, ist das natürlich kein Problem. Sie sollten lediglich eine begründeteMeinung vertreten (können). Und schließlich: Ist es gerade eine Position, die ichvertrete, die Sie zum Widerspruch reizt und dazu anregt, eine eigene Position zuentwickeln, umso besser!

1452.book Seite 20 Donnerstag, 5. August 2010 3:55 15

Page 18: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

21

Der Aufbau des Buches 1.2

1.2 Der Aufbau des Buches

Das folgende Kapitel 2 liefert zunächst Grundinformationen zu den verwendetenWerkzeugen und Ressourcen; dann beginnen die vier großen Teile, in die diesesBuch gegliedert ist. Diese Teile folgen dem Gedanken, dass ich zunächst dieGrundlagen, sowohl der Datenbank als auch der Programmiersprache PL/SQL,besprechen möchte. Danach folgt ein Teil, der sich mit der Anwendung von PL/SQL in konkreten Einsatzszenarien auseinandersetzt und weitergehende, techno-logische Konzepte erläutert. Den Abschluss bildet schließlich ein Teil mit konkre-ten Anwendungen in einer Form, die als Keimzelle für Ihre eigenen Projektedienlich sein könnte.

1.2.1 Teil 1: Grundlagen

Dieser Teil hat auf den ersten Blick eigentlich wenig mit PL/SQL zu tun. Erläutertwerden der Aufbau und die grundsätzliche Arbeitsweise der Oracle-Datenbank.Aus meiner Erfahrung aus unzähligen Oracle-Schulungen weiß ich allerdings, dassdas Wissen um diese Strukturen nicht vorausgesetzt werden kann. Andererseitsist es genau dieses Wissen, dass die meisten Empfehlungen der weiterenAbschnitte begründet und Sie in die Lage versetzt, die Folgen Ihrer Programmie-rung besser abschätzen zu lernen. Woraus besteht eine Datenbank? Wie wird einFremdschlüssel eigentlich durchgesetzt? Ist dieser Fremdschlüssel teuer? SolcheFragen werden gestellt und beantwortet. Allerdings führt dieser Teil Sie nocherheblich weiter, denn wir werden uns auch um Fragen der Konsistenz von Lese-abfragen, um Transaktionsschutz und ähnliche Probleme kümmern. Die Kenntnisdieser Dinge ist deshalb von fundamentaler Bedeutung für Sie als Entwickler, weildiese Dinge in jeder Datenbank anders gehandhabt werden und massive Auswir-kungen auf die Fehlerfreiheit und die Skalierbarkeit Ihrer Anwendungen haben.

Kapitel 3: Aufbau der Datenbank aus Sicht eines Programmierers

Dieses Kapitel beginnt den Rundblick mit einem Blick auf die Speicherstrukturender Datenbank, die Datenbankdateien und die zugeordneten Dateien wie etwadie Parameter- und Passwortdateien. Die Strukturen werden so erläutert, dass Sieeine Vorstellung von der Arbeitsweise bekommen und die Auswirkungen auf dieProgrammierung abschätzen können, nicht aber so, dass Sie anschließend alshauptamtlicher Administrator tätig werden können. Wir werden uns in diesemKapitel aber auch um die grundlegende Arbeit mit der Datenbank kümmern: umdas Anmelden und das Hoch- und Herunterfahren der Datenbank. Danach sehenwir uns die Datenstrukturen an, mit denen Sie auf logischer Ebene zu tun haben:Schema, Tablespace, die verschiedenen Datenbankobjekte. Den Abschluss macht

1452.book Seite 21 Donnerstag, 5. August 2010 3:55 15

Page 19: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

22

Einführung1

ein Exkurs in die Zeichensatzkodierung, die gerade im Zusammenhang mitDatenbanken von großer Bedeutung ist und oft Probleme nach sich zieht.

Kapitel 4: Datensicherheit, -konsistenz und Transaktion

Dieses Kapitel ist ein absoluter Schwerpunkt bezogen auf das Wissen, das Sie überOracle haben müssen, wenn Sie Anwendungen gegen eine Oracle-Datenbank pro-grammieren. Nirgendwo sonst sind die Implementierungsunterschiede zwischenDatenbankmanagementsystemen so groß und die Auswirkungen auf die Program-mierung so weitgehend. Wir werden in diesem Kapitel die Themen Schreib- undLesekonsistenz erläutern und uns um den Begriff der Transaktion kümmern.Schließlich werfen wir einen genaueren Blick auf das Themenfeld Datenkonsis-tenz und referenzielle Integrität, denn diese Punkte sind das zentrale Gut, das esin Ihrem Code zu verteidigen gilt. Anschließend betrachten wir das Sperrverfah-ren, das Oracle implementiert, um die Datenkonsistenz zu schützen, und sehenuns an, auf welche Weise Ihre Anwendung aufgebaut sein muss, um diese zu erhal-ten. Zum Abschluss des Kapitels fragen wir uns, wie Oracle eine SQL-Anweisungverarbeitet und diese Verarbeitung intern optimiert, und wir fragen uns, welcheAuswirkungen diese Betrachtungen auf Ihre Programmierstrategie haben.

Kapitel 5: Die Datenbank in der Anwendungsarchitektur

Dieses Kapitel nimmt insofern eine Sonderstellung ein, als es eine spezielle Ziel-gruppe hat: den Anwendungsentwickler mit Erfahrung in objektorientierten Pro-grammiersprachen. Gerade aus der Kombination objektorientierter Program-miersprachen und relationaler Datenbanken ergibt sich eine Reihe schwer zulösender Probleme. Diese Probleme werden als Impedance Mismatch zusammen-gefasst und müssen gelöst werden, damit Ihre Anwendung stabil und sicherarbeiten kann. In diesem Kapitel beleuchte ich das Problem und zeige die ver-schiedenen Lösungswege auf, die in der Industrie normalerweise für dieses Pro-blem verwendet werden.

Kapitel 6: Programmierung der Datenbank

Dieses Kapitel fasst die verschiedenen Einsatzbereiche zusammen, in denen PL/SQL innerhalb der Datenbank eingesetzt werden kann. Die Idee ist, Ihnen eineVorstellung von der Vielseitigkeit der Sprache zu geben. Oft ist man gefangen inden Problemlösungen, die man kennt, obwohl es bessere Wege zur Lösung einesProblems gibt. Ich werde Ihnen einige dieser Alternativen aufzeigen. Wirbeschäftigen uns in diesem Kapitel mit PL/SQL zur Erweiterung der Datenbank-funktionalität, zur Programmierung der Datenkonsistenz und -sicherheit, sehenuns die Anwendungsprogrammierung mit PL/SQL an und fragen uns, auf welcheWeise PL/SQL den Datenbankadministrator unterstützt.

1452.book Seite 22 Donnerstag, 5. August 2010 3:55 15

Page 20: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

23

Der Aufbau des Buches 1.2

1.2.2 Teil 2: Die Sprache PL/SQL

In diesem Teil beschäftigen wir uns mit der Sprache PL/SQL auf grundlegendemNiveau. Es geht in diesem Teil darum, die Sprache syntaktisch vorzustellen undzu zeigen, welches Instrumentarium PL/SQL zur Lösung von Problemen bietet.Was ist das Besondere an PL/SQL? Welche Gemeinsamkeiten, aber auch Unter-schiede gibt es zwischen PL/SQL und anderen Programmiersprachen?

Kapitel 7: Blockstruktur und Syntax von PL/SQL

In diesem Kapitel beginnen wir mit dem syntaktischen Aufbau von PL/SQL, sei-ner Blockstruktur, den Datentypen und Kontrollstrukturen. Dann sehen wir unsdie – naturgemäß sehr ausgebauten – Fähigkeiten der Datenbank in der Verwal-tung von Datenmengen an. Es schließt sich eine Einführung in dynamisches SQLund die objektorientierten Datentypen an. Mit diesem Instrumentarium habenSie die Einzelbausteine kennengelernt, aus denen PL/SQL-Programme bestehen.Das Kapitel schließt mit einem Rundblick über die online verfügbare Dokumen-tation der Sprache, die Sie für die tägliche Arbeit benötigen, um sich über kon-krete Funktionalitäten zu informieren.

Kapitel 8: Events in der Datenbank: Programmierung von Triggern

Trigger sind für viele Entwickler der Einstieg in die Programmierung von Daten-banken. Aber auch Administratoren haben oft mit dieser Art der Programmie-rung zu tun, um Geschäftsregeln durchzusetzen, Stammdatenänderungen zu pro-tokollieren oder Datensicherheitsbestimmungen durchzusetzen. Dieses Kapitelgibt einen Überblick über das – alles andere als triviale – Thema der Programmie-rung von Triggern. Wir beschäftigen uns mit »normalen« DML-Triggern, aberauch mit DDL-Triggern und sehen uns mögliche Einsatzbereiche an.

Kapitel 9: Das Arbeiten mit Daten

Die Kernaufgabe von PL/SQL-Programmen ist die Verarbeitung von Daten derDatenbank. Daher kommt den Mechanismen der Datenbearbeitung innerhalbvon PL/SQL eine besondere Bedeutung zu. Dieses Kapitel widmet sich ganz die-ser Aufgabe und zeigt zunächst die strukturierten Datentypen, die PL/SQL anbie-tet, im Kontext dieser Aufgaben. Anschließend sehen wir uns spezialisierte Kon-strukte von PL/SQL für diesen Einsatzzweck an, und Sie erlernen den korrektenUmgang mit Cursorn in der Datenbank.

Kapitel 10: Packages

PL/SQL-Code wird in Packages organisiert. Neben der Organisation von Codeblö-cken haben Packages aber noch weitergehende Funktionen, die in diesem Kapitel

1452.book Seite 23 Donnerstag, 5. August 2010 3:55 15

Page 21: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

24

Einführung1

beleuchtet werden. Wir sehen uns die Konzepte der Packages an und diskutierenderen Auswirkungen auf die Praxis der Programmierung. Außerdem sehen wiruns wichtige, mitgelieferte Oracle-Packages an, und ich gebe Ihnen Tipps, wieund wo Sie sich über weitere Packages informieren können.

Kapitel 11: Fehlerbehandlung

Die Fehlerbehandlung in PL/SQL-Programmen wird in diesem Kapitel unter-sucht. Wir beginnen mit einer Betrachtung der grundsätzlichen Arbeitsweise derFehlerbehandlung und überlegen, welche Alternativen für die Definition undBehandlung von Fehlern zur Verfügung stehen. Abschließend gebe ich Ihneneinige Empfehlungen zum sinnvollen Umgang mit Fehlern.

1.2.3 Teil 3: PL/SQL im Einsatz

Der dritte Teil des Buches beschäftigt sich mit dem Einsatz von PL/SQL. War Teil 2eher technisch orientiert, so gehen wir in diesem Teil die Probleme eher aufga-benorientiert an. Wir überlegen, mit welchen Mitteln und wofür PL/SQL genutztwerden kann, und betrachten die verschiedenen Möglichkeiten an kurzen Bei-spielen. Das Ziel dieses Teils ist einerseits, Ihnen Anregungen zum Einsatz vonPL/SQL zu geben und dies anhand von konkretem Code zu verdeutlichen. Ande-rerseits zeige ich Ihnen an dem erstellten Code PL/SQL in etwas größeren Zusam-menhängen und begründe Ihnen meine Entscheidung für die eine oder andereImplementierung.

Kapitel 12: Erweiterung von SQL

Dieses Kapitel betrachtet einige Beispiele für die Erweiterung des Befehlsum-fangs von SQL durch eigene PL/SQL-Funktionen. Wir starten damit, dass wir unsfragen, wann SQL überhaupt durch eigene Funktionen erweitert werden sollteund sehen uns dann an, wie diese Erweiterung durchgeführt werden kann. AlsKrönung werden wir eigene Gruppenfunktionen erstellen und einen Code-Gene-rator entwickeln, der Sie bei der Erstellung von Gruppenfunktionen unterstützt.

Kapitel 13: Arbeiten mit großen Datenstrukturen

Eine häufige (und häufig nicht vollständig verstandene) Anforderung an Daten-bankentwickler ist die Arbeit mit großen Datenstrukturen. Damit sind hier nichtgroße Ergebnismengen durch SQL-Abfragen gemeint, sondern große Datenstruk-turen wie Videos, Audiodateien oder große Textdateien. Bei Oracle können dieseStrukturen mühelos jeden Arbeitsspeicher sprengen und bedürfen daher einerbesonderen Behandlung. Diese Behandlung erläutere ich in diesem Kapitel. Wirsehen uns zunächst die technische Struktur dieser großen Datenstrukturen an

1452.book Seite 24 Donnerstag, 5. August 2010 3:55 15

Page 22: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

25

Der Aufbau des Buches 1.2

und analysieren anschließend die von Oracle zur Verfügung gestellten Packages,mit denen diese Strukturen verwaltet werden. Das Kapitel schließt mit einigenHilfspackages zum Schreiben und Lesen dieser Datenstrukturen vom und insDateisystem ab.

Kapitel 14: Arbeiten mit XML

Schon seit vielen Jahren unterstützt Oracle den Datentyp XML nativ. Dieses Kapi-tel beschäftigt sich mit diesem enorm umfangreichen Thema und gibt eine Ein-führung in die verschiedenen Strategien, mit denen XML innerhalb der Daten-bank erzeugt, gelesen und auf relationale Tabellen abgebildet werden kann.Allerdings liefert dieses Kapitel keine Einführung in XML oder die in diesemKapitel verwendeten Technologien wie XSLT oder XSD. Einiges wird nurerwähnt, anderes am Beispiel gezeigt. Gerade dieses Thema wäre ausreichend fürein eigenes Fachbuch (und solche Bücher gibt es natürlich zu diesem Thema).Doch für das grundlegende Verständnis dieser Technologie sollte das hier Darge-stellte durchaus reichen. Wir sehen uns zunächst den Datentyp XMLType an, mitdessen Hilfe XML in der Datenbank hauptsächlich gespeichert und bearbeitetwird. Dann sehen wir uns Strategien an, wie XML aus relationalen Daten erzeugtwerden und mit PL/SQL verarbeitet werden kann. Ein weiterer Teil beschäftigtsich mit dem Einlesen und Verteilen von XML in die Datenbank. Zum Teil liefertdieses Kapitel auch spezielle Funktionen von SQL, die ich hier aufgenommenhabe, weil sie nicht zum Standardwissen eines SQL-Entwicklers gehören, aller-dings in Kombination mit PL/SQL erforderlich sind, um XML zu verarbeiten. DasKapitel schließt mit einer Einführung in die XML-Datenbank, einer Anwendungder eingangs geschilderten XML-Datentypen zur Speicherung von XML und binä-ren Daten in der Datenbank über das Dateisystem.

Kapitel 15: Objektorientierung

Die Objektorientierung ist für Anwendungsentwickler mit entsprechendem Hin-tergrund oftmals der Heilsbringer, für Administratoren und Anwendungsent-wickler ohne diesen Hintergrund oftmals das Schimpfwort schlechthin. DiesesKapitel versucht zu schlichten: Einerseits bietet es eine Einführung in die Objekt-orientierung für diejenigen, die sich noch nicht entschließen konnten, dieseWeltsicht für sich zu entdecken, andererseits erläutert es für die anderen, warumdie Objektorientierung, gerade im Zusammenhang mit der strukturierten Spei-cherung großer Datenmengen, nicht die allein selig machende Technologie seinkann. Wahrscheinlich, das sehe ich schon kommen, werden beide Seiten nachder Lektüre nicht vollends zufrieden sein: Meine Einführung in die Objektorien-tierung dürfte denen, die die Technologie bereits mit Begeisterung einsetzen, zuoberflächlich, die Argumente gegen den hemmungslosen Einsatz von Objektori-

1452.book Seite 25 Donnerstag, 5. August 2010 3:55 15

Page 23: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

26

Einführung1

entierung innerhalb der Datenbank zu kleinlich sein, und die Gegner der Objekt-orientierung werden mir möglicherweise ein unvorteilhaft positives Bild derobjektorientierten Programmierung vorwerfen und den Aufwand, diese Techno-logie innerhalb der Datenbank anzuwenden, als unnötig hoch einstufen. Ichbleibe dennoch bei meiner Position der vorsichtigen Vermittlung zwischen denWelten und der Anbindung und Nutzung dort, wo es Sinn macht, und der Ableh-nung dort, wo der Sinn zu fehlen scheint. Das Kapitel beginnt also mit einer Ein-führung in die Objektorientierung »für Dummies« und zeigt an einem konkretenTyp die aus meiner Sicht sinnvolle Verwendung. Der Code dieses Kapitels istetwas länger als sonst üblich, zeigt aber auch mehrere Praktiken, nicht nur ausdem objektorientierten Umfeld, sondern auch bezüglich der Umsetzung in PL/SQL.

Kapitel 16: Integration von Oracle in Applikationen

Dieses Kapitel untersucht die verschiedenen Szenarien, in denen Oracle in Daten-banken integriert wird. Wir sehen uns die verschiedenen Sperrverfahren imCode an und erläutern verschiedene Wege der Umsetzung. Anschließend küm-mern wir uns darum, wie Daten einer externen Anwendung über das Netzwerk,aber auch über das Intra- oder Internet zur Verfügung gestellt werden kann. DieIdee hierbei ist, aufzuzeigen, dass Oracle sich nicht nur über direkte Datenbank-verbindungen befragen lässt, sondern auch Möglichkeiten der losen Kopplungbietet, bei denen die Datenbank als REST- oder SOAP-basierter Webservice-Pro-vider auftritt und so einen weiteren Zugriff auf die Daten der Datenbank gestat-tet. Bei Verbindungen über das lokale Netzwerk (ob nun direkt aus der Anwen-dung oder über einen Connection Pool eines Applikationsservers) zeige ichdarüber hinaus, auf welche Weise Daten durch den Datenbankserver vorgehaltenwerden. Spannend wird diese Frage ja vor dem Hintergrund der enormen Daten-mengen, die durch eine SQL-Anweisung eventuell über das Netzwerk geschobenwerden können.

1.2.4 Teil 4: Workshops

Der abschließende Teil des Buches widmet sich der Abbildung konkreter Pro-blemstellungen auf PL/SQL. Zum einen stelle ich eine Anwendungsarchitekturvor, die als Keimzelle für Ihre Projekte herangezogen werden kann, zum anderenzeige ich an einem horizontalen Dienst, auf welche Weise PL/SQL-Packages inIhre Anwendungen integriert werden können.

1452.book Seite 26 Donnerstag, 5. August 2010 3:55 15

Page 24: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

27

Danksagung 1.3

Kapitel 17: Workshop1 – Die Keimzelle sicherer Datenbankanwendungen

Dieses Kapitel fasst viele der in den vorangegangenen Kapiteln besprochenenTechniken zu einer Architektur zusammen, in der die Datenbank die Rolle eines»Datenframeworks« übernimmt. Diesen Begriff habe ich mit Blick auf Java-Ent-wickler gewählt, weil dort für alles und jedes »Frameworks« verwendet werden.Mir geht es darum, aufzuzeigen, wie die wirklich staunen machenden Fähigkei-ten der Oracle-Datenbank ideal genutzt werden können, um mit Bordmittelnund ein wenig Programmierung eine Datenbankarchitektur zu erzeugen, die einHöchstmaß an Skalierbarkeit und Sicherheit mitbringt und sich dennoch ganzeinfach in eine Anwendungsarchitektur einfügt. Dieses Kapitel ist eine Mischungaus SQL, Administrationswissen und PL/SQL und ist eigentlich insofern typischfür die Anwendungsentwicklung gegen Datenbanken, als eine optimale Lösungimmer auch die intime Kenntnis der eingesetzten Technologien erfordert. DiesesKapitel bietet sozusagen eine »Guided Tour« durch eine solche Datenbankanwen-dung und zeigt die Denkweise eines Entwicklers, der Oracle intensiv kennt undeinsetzt.

Kapitel 18: Workshop2 – Ein Logging-Package

Das letzte Kapitel des Buches gibt ein Beispiel für ein komplettes Package füreinen Einsatzzweck, der sich in jedem Projekt findet: ein Package für horizontaleDienste im Umfeld der Fehlerbehandlung und des Loggings. Als Keimzelle fürein entsprechendes Package für Ihre Projekte sollte dieses Projekt taugen. DieHighlights sind: Fehlermeldungen in beliebigen Sprachen, zentralisiertes Fehler-logging, Logging kompatibel zum weitverbreiteten Java-Standard Log4J (entspre-chende Implementierungen gibt es auch für andere Programmiersprachen) unddamit die Fähigkeit, Fehlermeldungen der Datenbank in den normalen Fehlerbe-handlungsfluss Ihrer Anwendung zu integrieren, und einiges mehr. Dieses Pro-jekt versammelt in sich einen ganzen Strauß verschiedener Programmiertechni-ken: Objektorientierung, XML, ein witziges Datenmodell, Advanced Queueingund einiges mehr. Seien Sie also gespannt!

1.3 Danksagung

Meine Frau bat mich, in diesem Buch auf eine Danksagung nach der Art: »Ichdanke meiner Familie, die mich viele Monate nicht zu Gesicht bekommen hat,für ihre Unterstützung« abzusehen, sondern – maximal – zu schreiben, dass, hättesie mich nicht freundlich, aber bestimmt zur Arbeit gedrängt, das Buch immernoch nicht fertig sei … Meine Frau hat Spaß daran, und ich habe Spaß an meinerFrau, also lasse ich das natürlich auch mit der Danksagung.

1452.book Seite 27 Donnerstag, 5. August 2010 3:55 15

Page 25: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

28

Einführung1

Allerdings muss ich (weil es mir besonders wichtig ist) einen herzlichen Dank anmeinen technischen Lektor, Joachim Zetzsche, aussprechen, der sich direkt undohne zu zögern bereit erklärt hat, die Kapitel fachlich gegenzulesen und seineAnmerkungen zu Stil, Komplexität und Art der Darstellung einzubringen. DieDiskussion mit ihm über den Inhalt und den Aufbau dieses Buches haben michenorm weitergebracht. Joachim ist einer der besten Kenner der Oracle-Daten-banktechnologie, den ich kenne, und mein Zutrauen, dass das, was ich über Oraclebehaupte, der Wahrheit nahekommt, steigt steil, nachdem Joachim sein Plazetdazu gegeben hat. Herzlichen Dank dafür!

Mein Dank gilt auch den übrigen Fachlektoren und Herrn Mattescheck von Gali-leo Press, der dieses Projekt betreut und Geduld mit mir hatte, als die Lieferter-mine von mir ein ums andere Mal verschoben wurden. Allerdings muss ich zumeiner Verteidigung auch sagen, dass die Aufgabe, neben dem täglichen Projekt-geschäft ein so dickes Buch zu schreiben, brachial unterschätzt wird …

Nicht zuletzt gilt mein Dank Ihnen, den Lesern, dafür, dass Sie sich die Zeit neh-men, dieses Buch zu lesen. Ich hoffe, Sie betrachten die investierte Zeit nicht alseine verlorene. Ich weiß, dass ich Ihnen da und dort erhebliche Konzentrationabverlangen muss, tue das aber in dem Bewusstsein, dass die Inhalte, die ich dortvermittele, für die Programmierung guter Anwendungen unerlässlich sind. DieAufgabe dieses Buches ist es, Ihnen zu erklären, wie man Oracle-Datenbankenrichtig programmiert. Nicht irgendwie. Sollte Ihnen dieses Buch auf dem Weg zusolchen Anwendungen hilfreich sein, freue ich mich über eine Rückmeldung.Falls nicht – vielleicht senden Sie eine Mail an den Verlag? Nein, im Ernst, auchüber Kritik freue ich mich, so sie denn konstruktiv ist und berücksichtigt, dassich, sollte ich gescheitert sein, dies nicht mit Vorsatz getan habe.

1452.book Seite 28 Donnerstag, 5. August 2010 3:55 15

Page 26: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

395

Die zentrale Aufgabenstellung für die Programmierung von PL/SQL ist der Umgang mit den Daten der Datenbank. PL/SQL ist für diese Auf-gabe besser gerüstet als jede andere Programmiersprache im Oracle-Umfeld, denn als Erweiterung zu SQL setzt sie direkt auf der Daten-banksprache auf. Grund genug, diese Vorteile zu nutzen!

9 Das Arbeiten mit Daten

In Abschnitt 7.4, »Kollektionen in PL/SQL«, haben Sie bereits den grundsätzli-chen Aufbau von Records, assoziativen Tabellen und so weiter kennengelernt.Dieses Kapitel vertieft nun dieses Wissen und stellt die einzelnen Datentypen inden Kontext von Anwendungen.

9.1 Strukturierte Variablen: Records und Typen

Beginnen wir mit den Records. Den grundsätzlichen Aufbau haben wir bereitsbesprochen, doch wo liegen Anwendungsbereiche über die Hauptanwendung,das Kopieren einer Tabellenzeile, hinaus?

9.1.1 Bindung an das Data Dictionary mit »%TYPE« und »%ROW-TYPE«

Bei der Bindung an das Data Dictionary folgt unser Code den Änderungen amDatenmodell. So gut diese Fähigkeit im Allgemeinen ist, so hinterhältig kann sieaber auch sein, denn sie stößt bei bestimmen Rahmenbedingungen halt an Gren-zen. Nehmen wir z.B. an, eine Tabelle wird durch eine neue Spalte erweitert.Dann wird dieser neuen Spalte natürlich in unserem Code niemals ein Wert zuge-wiesen, denn unser Code kennt diese Spalte nicht. Umgekehrt kann es sein, dasseine gelöschte Spalte einen Fehler auslöst, denn eine Zuweisung auf diese Spaltefunktioniert nun natürlich nicht mehr. Doch haben wir in diesem Beispiel dengroßen Vorteil, davon zu erfahren, denn nun kompiliert die Prozedur nichtmehr. Machen wir uns dies an einem Beispiel klar.

Ich hatte unserer Tabelle dept eine Spalte max_sal hinzugefügt, um einen schnel-len Ausweg aus einem Mutating-Table-Problem zu erhalten (siehe Abschnitt

1452.book Seite 395 Donnerstag, 5. August 2010 3:55 15

Page 27: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

396

Das Arbeiten mit Daten9

8.3.5, »Trigger und Datensichten (INSTEAD-OF-Trigger)«). Vielleicht habe ichmich nun doch entschlossen, einen anderen Weg zu verwenden, denn mir ist erstjetzt klar geworden, dass die zusätzliche Spalte das Problem eigentlich gar nichtgelöst, sondern nur verschoben hat: Wie pflege ich denn jetzt das Maximum derGehälter in der Tabelle dept, wenn konkurrierend die Gehälter der Benutzer inTabelle emp erhöht werden? Daher benötige ich diese Spalte nicht mehr. Leiderhabe ich eine Prozedur, die dieser Spalte einen Wert zugewiesen hat. DieseZuweisung gelingt nun natürlich nicht mehr. Doch wo war dieser Code noch ein-mal?

Irgendwo in unserem Code wird eine Zeile etwa dieser Art stehen:

declare dept_rec dept%ROWTYPE;begin… dept_rec.max_sal := max_sal;…

Diese Zeile wird vom Compiler nicht mehr kompiliert, denn der Record dept_recenthält keine Struktur mit dem Namen max_sal mehr. Nur zur Verdeutlichung:Hätten wir den Record explizit deklariert und nicht an das Data Dictionarygebunden, wäre dieser Fehler nicht aufgefallen, sondern zur Laufzeit aufgetreten.Die eigentliche Kunst für Oracle liegt aber gar nicht so sehr im Kompilieren die-ser Struktur, sondern darin, zu erkennen, dass irgendeine Änderung am DataDictionary genau diese Zeile Code ungültig macht. Denn zum Zeitpunkt desKompilierens existierte die Spalte noch in der Tabelle dept, die Spalte wurde erstgelöscht, nachdem dieser Code kompiliert war. Dennoch erkennt Oracle selbsttä-tig, dass diese Struktur nicht mehr gültig ist, weil sich die Voraussetzungen geän-dert haben. Im konkreten Fall setzt Oracle den Status dieser Prozedur auf den Sta-tus invalid und erlaubt die Ausführung nicht mehr. Sie erkennen also sofort,dass ein Problem vorliegt, und können es anschließend lösen. Die Verwaltungdieser Abhängigkeiten durch Oracle ist es, wovon Sie auch in diesem Beispielprofitieren.

Doch auch an diesem Beispiel können wir uns klarmachen, dass es keine Vorteileohne Nachteile gibt. Wir profitieren also von der Verwaltung der Abhängigkeitdurch Oracle, weil die Deklarationen aufeinander aufbauen. Denken wir diesesThema aber weiter, so wird klar, dass die Änderung einer zentralen Datenstruk-tur eventuell eine kaskadierende Kette von Neukompilierungen nach sich ziehenkann. Oracle bezeichnet so etwas als Abhängigkeitskette (dependency chain). AlsBeispiel nehmen wir ein Package mit Konstanten an, das von vielen anderenPackages referenziert wird. Ändere ich nun dieses zentrale Package, wird es

1452.book Seite 396 Donnerstag, 5. August 2010 3:55 15

Page 28: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

397

Strukturierte Variablen: Records und Typen 9.1

ungültig und mit ihm alle auf der Deklaration aufbauenden Packages, Prozedurenund Funktionen. Eine Anpassung eines zentralen Packages hat also das Neukom-pilieren vieler weiterer Packages zur Folge. Je nach Anwendungssituation kanndies ein Nachteil sein. Besonders ärgerlich ist dieses Neukompilieren, wenn esbei laufender Datenbank durchgeführt werden soll. Denn in diesem Fall ist essehr wahrscheinlich, dass Packages rekompiliert werden müssen, die von ande-ren Benutzer gerade verwendet werden. Diese Packages sind dann gesperrt, wer-den entsprechend nicht kompiliert, und ein Patch kann gefährdet sein.

Aber es gibt noch feinere Probleme. Was ist zum Beispiel, wenn Sie die zulässigeLänge einer Spalte beschränken? Vorher haben Sie 30 Zeichen erlaubt, nun nurnoch 25? Die Folgen von Änderungen dieser Art können von Oracle nicht immerkorrekt ausgewertet werden. Natürlich ist es möglich, einer Variablen den Werteiner anderen Variablen mit großzügigeren Grenzen zuzuordnen, solange diemaximale Länge der Variablen, der ein Wert zugewiesen wird, nicht überschrit-ten wird:

SQL> declare 2 a varchar2(10 char); 3 b varchar2(20 char) := 'Peter'; 4 begin 5 a := b; 6 end; 7 /PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.1 Beispiel für eine mögliche Variablenzuweisung

Es kann also sein, dass eine Verkürzung der Spaltenbreite für Oracle unproblema-tisch erscheint, dann aber zur Laufzeit Fehler auslöst, weil eine andere Variableimmer noch von der breiten Spalte ausgeht. Im Gegensatz dazu ist es im Regelfallunproblematisch, Datentypen zu erweitern. Eventuell können Sie von den erwei-terten Möglichkeiten nicht vollständig profitieren, ohne Ihren Code anzupassen,doch grundsätzlich sollten in dieser Konstellation keine Fehler auftauchen.

Ein anderer Problembereich ist die Änderung des Datentyps. Was geschieht,wenn eine Spalte, die vorher vom Typ varchar2 war, nun in den Typ date umge-wandelt wird? Sie sagen, dass so etwas passiere, sei doch wohl sehr unwahr-scheinlich? Ich weiß nicht, wie viele Datenmodelle ich schon gesehen habe, dieDatumsangaben als Zeichenketten speichern und im Zuge eines Redesigns end-lich auf den Typ Datum umstellen! Oracle wird versuchen, solange wie möglichmit impliziten Umwandlungen den Code »am Leben zu erhalten«, doch sind demnatürlich Grenzen gesetzt. Je nach Art der Überschreitung kann eine solche

1452.book Seite 397 Donnerstag, 5. August 2010 3:55 15

Page 29: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

398

Das Arbeiten mit Daten9

Grenze automatisch erkannt werden, zum Teil aber auch nicht. Allerdings giltnatürlich auch hier: Implizite Konvertierungen sollten Sie in Ihrem Code nichttolerieren. Manchmal ist dies zwar kaum sichtbar (etwa bei einer Schleifenvari-able, die vom Typ pls_integer ist und, wenn sie einer Variable vom Typ numberzugeordnet wird, konvertiert werden muss), doch in jedem Fall ist es schlechterProgrammierstil, etwa auf eine Standardumwandlung von Datumszeichenkettenin ein Datum zu hoffen. Wo immer dies unumgänglich ist, sollten Sie die Daten-typen explizit ineinander umwandeln.

Insgesamt gilt jedoch: Binden Sie Ihre Records an das Data Dictionary, wo immerdies möglich ist. Die Robustheit Ihres Codes nimmt zu, außerdem kommunizie-ren Sie klarer, was der Code eigentlich tun soll:

declare l_empno emp.empno%type; dept_rec dept%rowtype;begin …end;

Bei dieser Variablen müssen Sie nicht lange überlegen, welche Information in ihrwohl gespeichert werden soll. Ebenso gilt dies für die Deklaration der Recordva-riablen eine Zeile tiefer. Code dieser Art dokumentiert sich also selbst. Die Bin-dung an das Data Dictionary kann aber auch auf andere Weise als über die Bin-dung an eine Tabelle erfolgen. Eine gute Möglichkeit ist die Bindungen an dieDefinition einer Datenbanksicht oder an einen Cursor. Durch diese Möglichkei-ten können wir sehr gut steuern, welche Informationen unser Record enthaltensoll und welche nicht.

9.1.2 Insert- und Update-Anweisungen mit Records

Records können im Umfeld von Insert- oder Update-Anweisungen dazu genutztwerden, Daten »in einem Rutsch« in die Tabellen zu integrieren. Sehen wir unsdazu einige einfache Beispiele an. Im folgenden Beispiel wird ein Record mittelsdes %ROWTYPE-Attributs definiert und anschließend mit Werten für eine neueZeile gefüllt. Beachten Sie, dass der Aufruf der Sequenz departments_

seq.nextval in Zeile 4 in dieser direkten Form erst ab Version 11g möglich ist.In Oracle 10g müssten Sie eine Variable deklarieren und die Sequenz über eineSelect-Anweisung in die lokale Variable umkopieren:

SQL> declare 2 dept_rec departments%rowtype; 3 begin 4 dept_rec.department_id := departments_seq.nextval;

1452.book Seite 398 Donnerstag, 5. August 2010 3:55 15

Page 30: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

399

Strukturierte Variablen: Records und Typen 9.1

5 dept_rec.department_name := 'Accounting'; 6 dept_rec.manager_id := null; 7 dept_rec.location_id := 2700; 8 insert into departments values dept_rec; 9 end; 10 /PL/SQL-Prozedur erfolgreich abgeschlossen.SQL> select * 2 from departments 3 where location_id = 2700;DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID------------- ------------------------ ---------- ----------- 70 Public Relations 204 2700 280 Accounting 2700

Listing 9.2 Insert-Anweisung mittels eines Records

Ähnlich komfortabel ist die Integration eines Records in Update-Anweisungen.Vorab sollten Sie beachten, dass die einfach zu schreibende und zu benutzendeUpdate-Variante mittels %ROWTYPE alle Spalten ins Update nimmt, insbesondereauch die Primärschlüsselspalten, ob sich deren Inhalt nun ändert oder nicht. Dieshat zur Folge, dass eventuell referenziell abhängige Tabellen gesperrt werdenmüssen, wenn deren Fremdschlüsselspalte nicht indiziert ist. (Zur Begründungund Lösung dieses Problems siehe Abschnitt 4.3.2, »Performanzüberlegungen zuDatenbank-Constraints«). Zudem können Trigger ausgelöst werden, obwohlkeine relevante Spalte ihren Wert ändert. (Dieses Problem hatten wir inAbschnitt 8.1.1, »Anweisungs- versus Zeilentrigger«, besprochen). Aber sehenwir uns trotz dieser Warnhinweise diese Variante an:

SQL> declare 2 dept_rec departments%ROWTYPE; 3 begin 4 dept_rec.department_id := 280; 5 dept_rec.department_name := 'Administration'; 6 dept_rec.location_id := 2700; 7 update departments 8 set row = dept_rec 9 where department_id = 280; 10 end; 11 /PL/SQL-Prozedur erfolgreich abgeschlossen.

Sie erkennen die Pseudospalte row in Zeile 8. Diese Pseudospalte ist lediglichlinks des Gleichheitszeichens und hinter der (dann einzigen) set-Klausel erlaubt.

1452.book Seite 399 Donnerstag, 5. August 2010 3:55 15

Page 31: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

400

Das Arbeiten mit Daten9

Alle Werte, die vorher im Record nicht belegt wurden, werden durch Null-Werteersetzt.

Wenn Sie die Kontrolle über die Spalten, die aktualisiert werden sollen, behaltenmöchten, können Sie auch folgende Variante schreiben, die etwas länger ist,dafür aber gezielter agiert:

SQL> declare 2 dept_rec departments%ROWTYPE;

3 begin 4 -- Lies einen Datensatz in den Record 5 select *

6 into dept_rec 7 from departments 8 where department_id = 280;

9 -- Simuliere Datenänderungen durch den Anwender 10 dept_rec.department_name := 'Accounting'; 11 -- Schreibe die geänderten Daten in die Datenbank

12 update departments 13 set department_name = dept_rec.department_name, 14 location_id = dept_rec.location_id,

15 manager_id = dept_rec.manager_id 16 where department_id = dept_rec.department_id; 17 end;

18 /PL/SQL-Prozedur erfolgreich abgeschlossen.SQL> select *

2 from departments 3 where department_id = 280;DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID

------------- ------------------------ ---------- ----------- 280 Accounting 2700

Listing 9.3 Update-Anweisung mittels eines Records

Hier sehen Sie zudem, wie wir einen Datensatz aus der Datenbank lesen, einAttribut ändern und den geänderten Wert in die Datenbank zurückschreiben.Dies ist natürlich verkürzt, aber wir können uns eine Dialoganwendung vorstel-len, die einen Record aus der Datenbank liest, an ein Frontend gibt, den geänder-ten Record zurückerhält und anschließend in die Datenbank einliest. Gleichzeitigbehalten wir bei diesem Prozess die volle Kontrolle darüber, welche Spalte aktu-alisiert werden soll oder nicht.

1452.book Seite 400 Donnerstag, 5. August 2010 3:55 15

Page 32: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

401

Strukturierte Variablen: Records und Typen 9.1

9.1.3 Verwendung explizit deklarierter Records

Alle bisherigen Beispiele haben die Deklaration des Records in der ein oder ande-ren Form an das Data Dictionary gebunden, sei es über das Attribut %ROWTYPEoder über das Attribut %TYPE. Dies muss natürlich nicht so sein. Wenn Sie einenRecord explizit selbst deklarieren möchten, erinnert die syntaktische Form sehran die Definition einer Tabelle:

SQL> declare 2 type my_rec is record ( 3 id number not null := 0, 4 description varchar2(200 char), 5 content xmltype); 6 rec_var my_rec; 7 begin 8 < irgendeine Aktion … > 9 end; 10 /

Listing 9.4 Deklaration eines Records

Sie sehen, dass alle Einschränkungen, die wir für normale Variablen vornehmenkönnen, auch in Records erlaubt sind (allerdings keine Konstanten). Objektorien-tierte Entwickler entdecken in diesen Records vielleicht einen Struct wieder,aber auch außerhalb dieser Denkwelt sind Records praktische Strukturen, umz.B. die Anzahl der Parameter zu reduzieren, die an eine Prozedur übergebenoder von dort zurückerhalten werden. Leider ist aber die Übergabe eines Recordsan eine Prozedur nicht ohne Weiteres möglich: Der Record muss außerhalb derProzedur bekannt sein, damit die aufrufende Anweisung eine entsprechendeStruktur erzeugen oder entgegennehmen kann. Ein Record kann aber lediglichinnerhalb von PL/SQL definiert werden, ein create type my_rec is record… exis-tiert in SQL nicht.

Daher muss der Record im Rahmen eines Packages definiert und so »von außen«zugänglich gemacht worden sein. Die Programmierung mit Records als Parame-ter von Prozeduren oder Funktionen setzt also ein Package voraus. Sehen wir unsein kurzes Beispiel für eine solche Konstruktion an. In unserem Beispiel möchtenwir eine strukturierte Information übergeben, um im Rahmen einer Autorisie-rung einige Angaben zur Validierung zu übergeben. Wir möchten, dass eineAnmeldung einen korrekten Zeitstempel, einen Programmnamen und einen Ver-sionsstring übergibt. Anhand dieser Informationen können wir erkennen, wel-ches Programm die Autorisierung bei der Datenbank beantragt und in welcherVersion dieses vorliegt. Sie könnten sich vorstellen, dass wir eine solche Informa-

1452.book Seite 401 Donnerstag, 5. August 2010 3:55 15

Page 33: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

402

Das Arbeiten mit Daten9

tion in Kombination mit einem Benutzernamen und einem Passwort verwendenkönnen, um uns an einer Anwendung anzumelden. Da ich das Beispiel einfachhalten möchte, verzichte ich derzeit auf das Passwort und den Benutzernamen.Erstellen wir also zunächst ein Package:

SQL> create or replace package pkg_authorization 2 as 3 type app_rec_t is record ( 4 app_name char(5 char), 5 app_version char(5 char), 6 time_stamp date); 7 8 function authorize(app_rec in app_rec_t) 9 return boolean 10 ; 11 end pkg_authorization; 12 /Package wurde erstellt.

SQL> create or replace package body pkg_authorization 2 as 3 function authorize(app_rec in app_rec_t) 4 return boolean 5 as 6 two_minutes constant number := 2/1440; 7 begin 8 return app_rec.app_name = 'HDMAP' 9 and app_rec.app_version = '1.0.0' 10 and app_rec.time_stamp between sysdate - two_minutes and sysdate + two_minutes; 11 end authorize; 12 end pkg_authorization; 13 /Package Body wurde erstellt.

SQL> set serveroutput onSQL> declare 2 app_rec pkg_authorization.app_rec_t; 3 begin 4 app_rec.app_name := 'MY_AP'; 5 app_rec.app_version := '1.0.0'; 6 app_rec.time_stamp := sysdate; 7 if pkg_authorization.authorize(app_rec) 8 then

1452.book Seite 402 Donnerstag, 5. August 2010 3:55 15

Page 34: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

403

Strukturierte Variablen: Records und Typen 9.1

9 dbms_output.put_line('Autorisiert'); 10 else 11 dbms_output.put_line('Nicht autorisiert'); 12 end if; 13 end; 14 /AutorisiertPL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.5 Deklaration eines Records in einem Package

Sie erkennen die Deklaration des Recordtyps in der Package-Spezifikation.Anschließend wird eine Instanz des Records als Eingabeparameter der Funktionauthorize vereinbart, indem die Variable an die Deklaration des Records imPackage gebunden wird. Dies ist natürlich der Grund dafür, dass die Record-Deklaration in der Package-Spezifikation vorgenommen werden musste, ansons-ten wäre sie ja nicht sichtbar. Innerhalb der Prozedur authorize wird der über-gebene Parameter sozusagen »ausgepackt« und werden die einzelnen Bestand-teile mit vorgegebenen Werten verglichen. Das Ergebnis dieser Prüfung wirdanschließend als Wahrheitswert zurückgeliefert. Mithilfe dieser Technik ist nurein Parameter zu übergeben anstatt von drei zusammengehörigen Informatio-nen. Dadurch wird Ihr Code besser lesbar, zudem haben Sie eine leicht zu verar-beitende, selbsterklärende Struktur. Eines geht allerdings auch mit dieser Art derDeklaration nicht: Ein Record wird niemals direkt in SQL zu benutzen sein. SQLkennt keine Variablen, sondern maximal objektorientierte Typen, die für ähnli-che Zwecke gebraucht werden können.

Wenn Sie sich die Packages ansehen, die von Oracle mitgeliefert werden, stellenSie allerdings fest, dass diese Art der Programmierung von Oracle selbst nichtallzu häufig umgesetzt wird. Hier herrschen immer noch Prozeduren mit vielenParametern vor. Auf der Habenseite der herkömmlichen Art der Programmie-rung steht sicherlich, dass zum Aufruf der Prozedur kein Record erzeugt werdenmuss. Diese zusätzliche Komplexität mag einer einfachen Bedienung im Weg ste-hen. Zudem wird die Anzahl der Records, die Sie in einem umfangreichenPackage deklarieren müssen, doch recht hoch sein, zumal Sie einen Record fürjede überladene Prozedur definieren müssten. Auf der anderen Seite profitierenSie von kürzeren Funktionsaufrufen und möglicherweise klarerem Code. Letzt-lich ist es eine Stilfrage; funktionale Unterschiede sehe ich nicht. Beurteilen Siealso selbst, ob Sie diese Art der Programmierung mögen oder nicht. Ich ent-scheide mich tendenziell so: Prozeduren, die von Code außerhalb der Datenbankaufgerufen werden, versehe ich eher mit solchen Records als Prozeduren, dieinnerhalb der Datenbank aufgerufen werden. Das heißt, dass ich Prozeduren, die

1452.book Seite 403 Donnerstag, 5. August 2010 3:55 15

Page 35: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

404

Das Arbeiten mit Daten9

ich benötige, um einer Anwendung in Java oder C# oder was auch immer eineAPI zur Änderung meiner Daten anzubieten, als externes Interface gerne schlankhalten möchte. Gerne verwende ich für solche Parameter auch XML, wenn espasst, sodass eher eine nachrichtenartige Struktur beim Aufruf dieser Funktionenresultiert. Allerdings ist das lediglich meine persönliche Auffassung.

9.1.4 Verwendung der Returning-Klausel mit Records

Bei jedem Insert oder Update lassen sich im gleichen Round-Trip zum Serverauch einige Spalten über die Returning-Klausel zurückliefern. Sehen wir uns ineinem Beispiel an, wie eine Returning-Klausel einer SQL-Anweisung im Zusam-menhang mit einem Record genutzt werden kann. Die Returning-Klausel erlaubtes uns, nach einer DML-Anweisung eine oder mehrere Spaltenwerte zurückzulie-fern. Wenn wir mehrere Spalten benötigen, können wir zur Übergabe gut einenRecord verwenden. Diesen müssen wir so deklarieren, dass er alle Spalten auf-nehmen kann, die durch die Returning-Klausel geliefert werden. Daher könnenwir den Record nicht an die Definition der Tabelle binden, denn die Tabelle ent-hält zu viele Spalten. In unserem Beispiel wollen wir die Bewegung der Gehälterin einer Protokolltabelle hinterlegen. Dazu erstellen wir zunächst eine Tabelle,die diese Informationen aufnehmen kann:

SQL> create table emp_log as 2 select * 3 from emp 4 where 1=0;Tabelle wurde erstellt.

SQL> alter table emp_log add change_action varchar2(1 char);Tabelle wurde geändert.SQL> alter table emp_log add change_user varchar2(30 byte);Tabelle wurde geändert.SQL> alter table emp_log add change_date date;Tabelle wurde geändert.

Dann benötigen wir noch eine Prozedur, mit deren Hilfe wir die Gehälter anhe-ben (oder absenken) können. Diese Prozedur soll gleichzeitig auch die Einträge indie Protokolltabelle vornehmen. Auf diese Weise ersparen wir uns einen Triggerauf die Tabelle emp. Wir können uns die folgende Prozedur vielleicht als Teil einerMitarbeiter-Wartungs-API vorstellen:

SQL> create or replace 2 procedure raise_sal( 3 emp_id in emp.empno%type, 4 raise_factor in number := 1)

1452.book Seite 404 Donnerstag, 5. August 2010 3:55 15

Page 36: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

405

Strukturierte Variablen: Records und Typen 9.1

5 as 6 type emp_rec_t is record ( 7 ename emp.ename%TYPE, 8 sal emp.sal%TYPE); 9 emp_rec emp_rec_t; 10 begin 11 update emp 12 set sal = sal * raise_factor 13 where empno = emp_id 14 returning ename, sal into emp_rec; 15 if SQL%ROWCOUNT > 0 then 16 insert into emp_log 17 (empno, ename, sal, change_action, change_user, change_date) 18 values (emp_id, emp_rec.ename, emp_rec.sal, 'U', user, sysdate); 19 end if; 20 end; 21 /Prozedur wurde erstellt.

Listing 9.6 Beispiel für einen Record in einer Returning-Klausel

Beachten Sie, wie die aktualisierten Informationen durch die Returning-Klauselzurückgeliefert und in der nächsten Insert-Anweisung verwendet werden. Damitdiese Art der Zuweisung funktioniert, muss der Record selbstverständlich positi-onal exakt so definiert werden, wie die Werte in der Returning-Klausel geliefertwerden – sowohl von der Anzahl als auch vom Datentyp her. Das heißt, dass dieReturning-Klausel in unserem Beispiel zwei Record-Attribute erwartet und dassdas erste Attribut ein ausreichend großer Varchar2-Datentyp und das zweiteAttribut ein Number-Datentyp sein muss. Die Datenbank kümmert sich aller-dings nicht um die Bezeichnungen der Record-Strukturen und wird auch Daten-typen umwandeln, falls das möglich ist.

Eine Erwähnung verdient vielleicht noch die Zeile 15. Dort wird der Cursor SQLdaraufhin geprüft, wie viele Zeilen er bearbeitet hat. Der Cursor SQL ist einBezeichner für den implizit von Oracle genutzten Cursor, um die Update-Anwei-sung auszuführen. Hier wird das Cursorattribut ROWCOUNT verwendet, das dieAnzahl der verarbeiteten Zeilen enthält. Sollte eine ungültige Mitarbeiter-IDübergeben worden sein, führt die Update-Anweisung keine Änderung aus, undes wird auch kein Datensatz in die Logtabelle geschrieben.

Sehen wir uns die Returning-Klausel abschließend für eine Update-Anweisungan:

1452.book Seite 405 Donnerstag, 5. August 2010 3:55 15

Page 37: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

406

Das Arbeiten mit Daten9

SQL> declare 2 type emp_rec_type is record ( 3 last_name employees.last_name%TYPE, 4 salary employees.salary%TYPE); 5 emp_rec emp_rec_type; 6 begin 7 update employees 8 set salary = salary * 1.05 9 where employee_id = 106 10 returning last_name, salary into emp_rec; 11 -- Ausgabe mit returnierten Werten erzeugen 12 dbms_output.put_line( 13 'Das Gehalt für Mitarbeiter ' || emp_rec.last_name || 14 ' beträgt nun Taler ' || emp_rec.salary); 15* end;Das Gehalt für Mitarbeiter Pataballa beträgt nun Taler 5040PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.7 Returning-Klausel in einer Update-Anweisung

9.1.5 Alternative zum Record: Objekt

Als Alternative zum Record ist auch ein selbst definierter Datentyp denkbar,denn dieser Typ kann ebenfalls mehrere unterschiedliche Datentypen zu einemKonstrukt zusammenfassen. Mit diesem Typ machen wir den Schritt in dieObjektorientierung, die seit Version 8 langsam, aber unaufhaltsam Einzug in dieOracle-Datenbank gehalten hat. Der Fokus dieses Abschnittes ist es aber nicht,diese Technik im Detail zu beschreiben, daher soll nur ein kurzes Beispiel für dieVerwendung eines simplen Typs gegeben werden, und zwar insofern, als sichdessen Verwendung mit der eines Records deckt. Zur Deklaration eines Typswird eine SQL-Anweisung verwendet, dieser Typ ist also ein Datenbankobjektund mithin schemaweit sichtbar (mindestens, denn die Sichtbarkeit kann, wiebei jedem anderen Datenbankobjekt auch, über Grant-Anweisungen an andereBenutzer erweitert werden). So ist dann die schlichte Verwendung als Record-Ersatz etwas aufwendiger in der Definition, bringt aber eben auch keine wesent-lichen Vorteile gegenüber einem Record, sondern erfordert neben der externenDeklaration auch noch den Aufruf der Konstruktormethode <name_des_typs>(),um eine Instanz dieses Typs zu erstellen:

SQL> -- In SQL:SQL> create type my_type is object( 2 name varchar2(80 char), 3 job varchar2(30 char)); 4 /Typ wurde erstellt.

1452.book Seite 406 Donnerstag, 5. August 2010 3:55 15

Page 38: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

407

PL/SQL-Kollektionen 9.2

Achten Sie darauf, dass SQL*Plus das abschließende Zeichen »/« verlangt, wennSie ein Objekt deklarieren.

SQL> set serveroutput onSQL> declare 2 local_type my_type; 3 begin 4 local_type := my_type('MÜLLER', 'REVISOR'); 5 dbms_output.put_line(local_type.job); 6 end; 7 /REVISORPL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.8 Objekt als Record-Alternative

In dieser simplen Variante ist der objektorientierte Typ keine Alternative zumRecord. Er wird hier eher der Vollständigkeit halber erwähnt. Weitere Informa-tionen finden Sie in Kapitel 15, »Objektorientierung«, wo ich diesen Typ nichtnur genauer erklären, sondern auch bestechendere Einsatzszenarien zeigenwerde. Ein Vorteil ist allerdings schon hier sichtbar: Ein Objekt ist in SQL sicht-und benutzbar, ein Record als PL/SQL-Variable nicht!

9.2 PL/SQL-Kollektionen

Nachdem wir uns in Abschnitt 7.4, »Kollektionen in PL/SQL«, bereits mit denGrundlagen von Kollektionen vertraut gemacht haben, folgen nun einige weiter-führende Beispiele und Anwendungsbereiche.

9.2.1 Verwendung von assoziativen Tabellen

Die erste Gruppe von Kollektionen stellen die assoziativen Tabellen dar. DieseStrukturen, die nur in PL/SQL eingesetzt und nicht in der Datenbank gespeichertwerden können, sind im Grunde Tabellen mit einem Schlüssel- und einem Nutz-wert. Der Schlüsselwert dient ausschließlich dazu, einen Nutzwert in der assozi-ativen Tabelle wiederzufinden. Er muss daher eindeutig sein und kann entwedereine Zahl oder eine Zeichenkette sein. Sie definieren ein solches assoziativesArray wie folgt:

SQL> declare 2 type name_tab is table of emp.ename%type 3 index by binary_integer; 4 begin

1452.book Seite 407 Donnerstag, 5. August 2010 3:55 15

Page 39: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

408

Das Arbeiten mit Daten9

5 … 6 end; 7 /

In diesem Beispiel habe ich als Schlüsselwert eine Zahl verwendet. PL/SQL defi-niert hier den Datentyp binary_integer, der Ganzzahlen zwischen –2147483648und 2147483647 erlaubt (32 Bit) und im Übrigen mit dem Datentyp pls_integersynonym ist. Im Beispiel ist es naheliegend, als Schlüsselwert für die Tabelle dieMitarbeiternummer aus der Spalte empno zu verwenden, was insofern eine guteIdee ist, als damit direkt auch klar wird, dass die Schlüsselwerte durchaus nichtbei 1 beginnen und – wie ein Index – hochgezählt werden müssen, sondern belie-big gewählt werden können. Als Nutzwert habe ich hier eine Zeichenkette (denNachnamen des Mitarbeiters) gewählt, aber auch das muss nicht so sein. Sie kön-nen beliebige Datentypen verwenden und insbesondere auch einen Record.Damit ergibt sich eine Datenstruktur, die im Notfall eine ganze Tabelle aufneh-men könnte, wie das folgende Beispiel zeigt:

SQL> declare 2 type emp_tab is table of emp%rowtype 3 index by binary_integer; 4 begin 5 … 6 end; 7 /

Listing 9.9 Einfache assoziative Tabellen

Durch diese Deklaration könnte sich also endlich ein Weg ergeben, mit ganzenTabellendaten auf einmal arbeiten zu können. Doch ist diese Möglichkeit wahr-scheinlich nicht der beste Weg, denn Sie müssen im Hinterkopf behalten, dassdie Daten eines Records physikalisch in den Arbeitsspeicher umkopiert werden.Bei sehr großen Tabellen ist das sicherlich keine gute Idee. Besser wäre es, großeDatenmengen lediglich zu referenzieren und dort zu lassen, wo sie ohnehinbereits existieren, auf der Platte oder im Hauptspeicher der Datenbank nämlich.Diese Option steht uns mit den Cursorn zur Verfügung und soll dort auch bespro-chen werden.

Wenn diese Anwendung also nicht sinnvoll ist, wofür benötigen wir dann asso-ziative Tabellen? Einerseits ist ihr oben genannter Nachteil auch ein entscheiden-der Vorteil: Da die assoziativen Tabellen die Daten lokal vorhalten, entfällt (even-tuell) der Netzwerk- und Festplattenplatz, den die Daten benötigten, wären sie inTabellen gespeichert. Zudem können Sie diese Strukturen in Packages deklarie-ren und initial mit Daten füllen, die für die Dauer der Session genutzt werden sol-

1452.book Seite 408 Donnerstag, 5. August 2010 3:55 15

Page 40: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

409

PL/SQL-Kollektionen 9.2

len. Dadurch entfällt das andauernde Nachladen der Daten. Ideal ist diese Daten-struktur also dort, wo eine geringere Datenmenge lokal vorgehalten und schnellverfügbar gemacht werden muss. Natürlich muss zudem sichergestellt sein, dassdiese Daten während der Dauer der Benutzung nicht angepasst werden müssen,falls die zugrunde liegenden Daten sich ändern sollten. Ich verwende diese Struk-turen zum Beispiel gern in Packages, um Startwerte initial zu laden. Stellen Siesich vielleicht eine Liste von Währungskursen vor. Für unser Beispiel soll es aus-reichen, dass die Umrechnungskurse der Europäischen Zentralbank zugrundegelegt werden, die von der Bank einmal täglich veröffentlicht werden. DieseAktion ist natürlich zeitlich aufwendig, da die Kurse über eine entfernte Res-source geladen werden müssen. Andererseits sind nicht viele Kurse zu laden,sodass es sich anbietet, die Daten lokal vorzuhalten und nur nachzuladen, wennsie älter als einen Tag sind. Die Implementierung dieses Beispiels werde ich nach-holen, wenn ich Ihnen die objektorientierten Fähigkeiten der Datenbankgenauer vorstelle.

Dann sind assoziative Tabellen perfekt geeignet, um eine Menge von Datenbank-zeilen im Code zu berechnen und anschließend in einer Bulk-Operation an dieDatenbank zu übergeben. Da diese Verwendung sehr häufig geschieht, stelle ichsie im folgenden Abschnitt gesondert vor.

9.2.2 Massenverarbeitung mit assoziativen Tabellen

In Abschnitt 4.8, »Beispiel zum Einfluss der Programmierung«, habe ich in einemetwas fiktionalen Szenario den großen Einfluss der Programmierstrategie auf diePerformanz und Skalierbarkeit der Anwendung gezeigt. Eine Kernaussage desKapitels war, dass Datenbanken mengenorientiert und nicht satzweise program-miert werden sollten. Das Beispiel verwendete folgenden Code-Ausschnitt, umeine mengenorientierte Programmierung zu realisieren:

SQL> create or replace procedure SQL_performance_test_5 2 as 3 type value_table_type is table of pls_integer 4 index by binary_integer; 5 value_table value_table_type; 6 iterations integer := 10000; 7 begin 8 for i in 1..iterations loop 9 value_table(i) := i; 10 end loop; 11 forall indx in 1 .. iterations 12 insert into test_table values(value_table(indx)); 13 commit;

1452.book Seite 409 Donnerstag, 5. August 2010 3:55 15

Page 41: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

410

Das Arbeiten mit Daten9

14 end; 15 /

Listing 9.10 Verwendung einer assoziativen Tabelle in Bulk-Anweisungen

Mit dem bislang aufgebauten Wissen über PL/SQL können wir diesen Code nundeutlich besser verstehen: Wir erzeugen eine assoziative Tabelle value_table_type, von dem wir die Variable value_table ableiten. Anschließend kopieren wirdie Zahlen von 1 bis 10.000 in diese assoziative Tabelle. Wir wissen nun, dassdiese Daten mithin nicht in die Datenbank, sondern im Arbeitsspeicher gespei-chert werden (müssen, das vermerken wir hier direkt als Nachteil dieserMethode). Anschließend wird die assoziative Tabelle als Ganzes der Insert-Anweisung übergeben, die anschließend die Werte in einem Rutsch in die Daten-banktabelle einfügt. Inhaltlich entsteht folgender Pseudocode:

insert into test_tableselect * from value_table;

Listing 9.11 Pseudocode einer Bulk-Anweisung

Die entscheidende Anweisung ist die Forall-Anweisung in Zeile 11. Sehen wiruns diese Anweisung etwas genauer an. Auch wenn der Eindruck erweckt wird,ist die Forall-Anweisung keine Schleife, sondern eine Anweisung, die dazu dient,den übergebenen Parameter in Form einer SQL-Anweisung als dynamisches SQLauszuführen und dabei in sinnvoller Weise die übergebenen Parameterwerte zubinden. Die Verwendung dieser Anweisung erfordert eine gewisse Vorarbeit,denn die einzufügenden Parameter müssen als Kollektion vorliegen, in unseremFall als assoziative Tabelle, es geht aber auch eine geschachtelte Tabelle. Im Falleiner assoziativen Tabelle funktionieren allerdings lediglich solche mit einempls_integer-Schlüsselwert, nicht jedoch solche mit einem varchar2-Schlüssel.Zudem existieren einige Einschränkungen bezüglich des SQLs und der Referenzauf die Schlüsselwerte, die sich vielleicht so zusammenfassen lassen:

� Verwenden Sie ein SQL, das so einfach wie irgend möglich ist.

� Verweisen Sie auf die Indizes lediglich in einfacher (und nicht berechneter)Form, sagen Sie also value_table(indx) und nicht value_table(indx+1).

� Verwenden Sie eine Kollektion nicht sowohl in der Spaltenliste einer Update-Anweisung als auch in der Where-Klausel der Update-Anweisung.

Die konkreten Einschränkungen variieren mit der Datenbankversion und bezie-hen sich auch auf Randbereiche wie z.B. spärlich besetzte Kollektionen etc. Zum

1452.book Seite 410 Donnerstag, 5. August 2010 3:55 15

Page 42: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

411

PL/SQL-Kollektionen 9.2

tieferen Verständnis dieser Einschränkungen möchte ich gern auf die Online-Dokumentation (PL/SQL Language Guide, FORALL-Statement) verweisen, dennsie sind zum Teil recht speziell und Erläuterungen dazu würden den Rahmen desBuches definitiv sprengen.

In dieser einfachen Form wie im Beispiel oben haben wir einen hohen Preis fürdie Optimierung der Insert-Anweisung gezahlt, denn wir müssen immerhin alle10.000 Zeilen im Arbeitsspeicher vorhalten. In der Praxis wird so etwas eher sel-ten gemacht, denn die Optimierung stellt sich als Balance zwischen zwei wider-strebenden Anforderungen dar, wie in Abbildung 9.1 schematisch dargestellt ist:Auf der einen Seite soll der Durchsatz maximal, auf der anderen Seite aber derArbeitsspeicherbedarf minimal sein. Bei meinen Untersuchungen zu diesemThema bin ich auf folgenden, groben Zusammenhang gestoßen: Die Optimie-rungseffekte sind bereits bei relativ kleinen Bulkgrößen sehr deutlich spürbar undnehmen bei größeren Bulkgrößen nicht linear zu, sondern steigen zunehmendlangsamer. So gibt es also ein Optimum, das von vielen Faktoren abhängt, aberbei meinen Szenarien, die ich getestet habe, bereits bei wenigen 100 Zeilen proBulk absolut akzeptable Ergebnisse erzielte. Ich gehe sicher davon aus, dass dieZeilenlänge eine ebenso wesentliche Rolle spielt wie die gesamte zur Verfügungstehende Infrastruktur (Arbeitsspeicher, Prozessorgeschwindigkeit und -anzahl,Netzwerk- und Plattengeschwindigkeit etc.), daher möchte ich keine konkreteEmpfehlung geben. Wichtiger ist: Wie kontrollieren Sie die Größe des Bulks über-haupt?

Abbildung 9.1 Abhängigkeit der Ausführungsgeschwindigkeit von der Bulkgröße

Arbeitsspeicherbedarf

Zeit

Bulkgröße

1452.book Seite 411 Donnerstag, 5. August 2010 3:55 15

Page 43: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

412

Das Arbeiten mit Daten9

Die einfachste Variante ist natürlich, die lokale Kollektion immer nur mit ent-sprechend vielen Zeilen zu füllen und die Forall-Anweisung bei Bedarf aufzuru-fen. Dieses Codebeispiel liefert zudem endlich einmal eine sinnvolle Anwendungder MOD-Funktion:

SQL> set timing onSQL> create or replace procedure SQL_performance_test_5 2 as 3 type value_table_type is table of pls_integer 4 index by binary_integer; 5 value_table value_table_type; 6 iterations integer := 10000; 7 idx integer := 0; 8 begin 9 for i in 1..iterations loop 10 idx := idx + 1; 11 value_table(idx) := i; 12 if mod(i, 100) = 0 or i = iterations then 13 forall indx in 1 .. 100 14 insert into test_table values(value_table(indx)); 15 value_table.delete(); 16 idx := 0; 17 end if; 18 end loop; 19 commit; 20 end; 21 /Prozedur wurde erstellt.SQL> call SQL_performance_test_5();Aufruf wurde abgeschlossen.Abgelaufen: 00:00:00.14

Listing 9.12 Balancierung einer Bulk-Anweisung zwischen Performanz und Ressourcenverbrauch

Eine andere Möglichkeit besteht darin, die Forall-Anweisung so anzupassen, dassnur Teilmengen eingefügt werden. Dies kann dadurch erreicht werden, dasseben andere Begrenzungszahlen eingefügt werden. Doch hilft das nicht bei unse-rem Problem mit dem Arbeitsspeicher, denn auch in diesem Fall müsste die Kol-lektion ja komplett aufgebaut im Arbeitsspeicher vorhanden sein. Sie sehen, dasseiniger Aufwand betrieben werden muss, um diese Performanzvorteile zu nut-zen. Andererseits ist der Erfolg aber auch so spektakulär, dass sich der Aufwandlohnt.

1452.book Seite 412 Donnerstag, 5. August 2010 3:55 15

Page 44: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

413

PL/SQL-Kollektionen 9.2

Fehlerbehandlung bei Bulk-Operationen

Beim Schreiben im Bulk stellt sich zudem noch ein wesentliches Problem: Wiewird mit Fehlern umgegangen, die die Schreibprozesse ausführen? Hier stehenwieder einmal mehrere Möglichkeiten zur Verfügung. Bei der »normalen« Ver-wendung, wie im vorigen Abschnitt beschrieben, werden eventuelle DML-Fehlersofort ausgelöst und die gesamte Aktion rückgängig gemacht. Allerdings stehteine optionale Klausel zur Verfügung, die dieses Verhalten ändert und alle auftre-tenden Fehler bis zum Ende der Forall-Anweisung speichert, die erfolgreichenAktivitäten jedoch belässt:

forall indx in 1 .. 100 insert into test_table values(value_table(indx)) save exceptions;

Mit dieser zusätzlichen Klausel wird bei eventuell auftretenden Fehlern ein Attri-but bulk_exceptions (für den Cursor SQL) gefüllt, das nach der Ausführung abge-fragt werden kann. Am Ende der Arbeit wird dann nur noch ein einzelner Fehler(ora-24381) ausgelöst, der anzeigt, dass überhaupt Fehler während der Verarbei-tung aufgetreten sind. Dieser Fehler muss im Code zunächst abgefangen werden,damit im Exception-Teil des Codes die Fehlerliste explizit geprüft werden kann:

SQL> create or replace procedure SQL_performance_test_5 2 as 3 type value_table_type is table of pls_integer 4 index by binary_integer; 5 value_table value_table_type; 6 iterations number := 10000; 7 err_amount number; 8 dml_errors exception; 9 pragma exception_init(dml_errors, -24381); 10 procedure print(text in varchar2) 11 as 12 begin 13 dbms_output.put_line(text); 14 end; 15 begin 16 for i in 1..iterations loop 17 value_table(i) := i; 18 end loop; 19 forall indx in 1 .. iterations 20 save exceptions 21 insert into test_table values(value_table(indx)); 22 commit; 23 exception

1452.book Seite 413 Donnerstag, 5. August 2010 3:55 15

Page 45: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

414

Das Arbeiten mit Daten9

24 when dml_errors then 25 err_amount := sql%bulk_exceptions.count; 26 print('Fehler während der Ausführung: ' || err_amount); 27 for I in 1 .. err_amount loop 28 print('.- Nr. ' || i || ', Iteration: ' || 29 sql%bulk_exceptions(i).error_index); 30 print('. Meldung: ' || 31 sqlerrm(-sql%bulk_exceptions(i).error_code)); 32 end loop; 33 end; 34 /Prozedur wurde erstellt.

Um bei der Ausführung dieser Prozedur nun Fehler provozieren zu können, neh-men wir folgende Veränderungen vor: Zum einen wird die Tabelle auf Zahlen bis9999 begrenzt, zum anderen füge ich eine Zeile ein und verschärfe das Datenmo-dell durch einen Unique-Constraint:

SQL> alter table test_table add constraint u_test_table unique(id);Tabelle wurde geändert.SQL> alter table test_table modify (id number(4,0));Tabelle wurde geändert.SQL> insert into test_table values(123);1 Zeile wurde erstellt.SQL> commit;Transaktion mit COMMIT abgeschlossen.

Nun sollte ein erneutes Ausführen der Prozedur einen Fehlerbericht ergeben:

SQL> set serveroutput onSQL> call sql_performance_test_5();Fehler während der Ausführung: 2.- Nr. 1, Iteration: 123. Meldung: ORA-00001: Unique Constraint (.) verletzt.- Nr. 2, Iteration: 10000. Meldung: ORA-01438: Wert größer als die angegebene Gesamststellenzahl, die für diese Spalte zulässig istAufruf wurde abgeschlossen.

Listing 9.13 Bulk-Anweisung mit Fehlerbehandlung

Bulk-Select

Sehen wir uns noch eine weitere Anwendung an, die ebenfalls häufig verwendetwird: das Lesen im Bulk. Bei dieser Anwendung müssen viele Werte aus einer

1452.book Seite 414 Donnerstag, 5. August 2010 3:55 15

Page 46: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

415

PL/SQL-Kollektionen 9.2

Tabelle in eine lokale Variable umkopiert werden. Es soll kein Cursor eingesetztwerden, denn die Daten sollen z.B. in einem Package persistiert werden. In die-sem Fall bietet es sich an, die Leseoperation im Bulk durchzuführen, wie im fol-genden Beispiel, in dem die Tabelle dept in eine lokale geschachtelte Tabelleumkopiert werden soll:

SQL> declare 2 type dept_tab_t is table of dept%rowtype; 3 dept_tab dept_tab_t; 4 begin 5 select * 6 bulk collect into dept_tab 7 from dept 8 order by deptno; 9 end; 10 /PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.14 Bulk-Select-Anweisung

Das liest sich gut: Hier ist es lediglich erforderlich, eine Kollektion im richtigenTyp zur Aufnahme der Daten anzubieten und anschließend die Select-Anweisungum die Klausel bulk collect into zu erweitern. Achten Sie aber auch hier auf denSpeicherverbrauch: Dieses Verfahren ist nicht geeignet, um SQL »besser« zumachen. Die mit einer SQL-Anweisung verbundenen Datenmengen könnenwirklich erheblich sein. Diese Anweisung kopiert diese Daten in den Arbeitsspei-cher, und zwar so lange, bis dieser dicke Backen macht. Zudem müssen Sie über-legen, ob Sie bei der Ausführung einer solchen Anweisung noch andere Benutzerauf der Datenbank haben, die vielleicht Ähnliches vorhaben. Konkret empfehleich diese Anweisung, wenn Sie ohnehin eine lokale Kopie der Daten vorhaltenmüssen. Dann kommen Sie um den Speicherplatz nicht herum, und dann istdiese Art der Anweisung wahrscheinlich schneller als die »normale« Iterationüber einen Cursor.

9.2.3 Tabellenfunktionen (PIPELINED-Functions)

Prozeduren oder Funktionen, die Daten, z.B. in einer Schleife, berechnen, tundies im Normalfall komplett, bevor sie das Ergebnis zurückliefern. Dieses Verhal-ten hat den Vorteil, dass es einfach zu implementieren ist, und ist normalerweiseauch ausreichend. In Datenbanken jedoch stehen wir oft vor dem Problem, sehrgroße Datenmengen bearbeiten zu müssen. Werden diese großen Datenmengendurch eine PL/SQL-Funktion geschleust, kann das zur Folge haben, dass dieAnforderungen an den Arbeitsspeicher die Bearbeitung stark verlangsamen oder

1452.book Seite 415 Donnerstag, 5. August 2010 3:55 15

Page 47: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

416

Das Arbeiten mit Daten9

eventuell sogar unmöglich machen können. Zudem gibt es häufig Situationen, indenen die Ergebnisse einer Prozedur durch andere Anweisungen weiterverarbei-tet werden müssen. Es ist häufig möglich, bereits mit Teilergebnissen weiterzuar-beiten, die Funktion muss also nicht komplett bearbeitet werden, bevor dernächste Arbeitsschritt ausgeführt werden kann. In solchen Situationen wäre essinnvoll, die Teilergebnisse bereits an einen anderen Prozessor weiterzureichen,während die Funktion noch andere Informationen bearbeitet.

Für solche Funktionen können Funktionen so definiert werden, dass sie Teiler-gebnisse aus der laufenden Funktion heraus zurückliefern. Damit dies funktio-niert, muss die Funktion einen Kollektionstyp zurückliefern und mit der Klauselpipelined definiert werden. Vielleicht ist es auch hier wieder das Einfachste,wenn ich Ihnen ein Beispiel zeige. Die XML-Datenbank (XDB) stellt Ihnen eineMöglichkeit zur Verfügung, Daten in einer Ordnerhierarchie innerhalb derDatenbank zu speichern. Letztlich wird dabei für jeden Ordner eine Zeile in einerDatenbanktabelle angelegt und mittels des Protokolls WebDAV so angezeigt, alssei dies ein Dateisystem. Sie können neue Ordner in dieser Tabelle anlegen,unterliegen dabei aber der Beschränkung, dass nur Unterordner in bestehendenOrdnern angelegt werden können. Möchten Sie also auf einen Rutsch ein Ver-zeichnis, z.B. /etc/examples/pl_sql/chap_2 anlegen, so müssen Sie zunächstsicherstellen, dass das Verzeichnis /etc, dann das Verzeichnis /etc/examplesund so weiter existiert. Existieren diese Verzeichnisse nicht, so müssen sie nach-einander angelegt werden.

Um nun also beliebige Ordner anlegen zu können, benötigen wir eine Funktion,die uns diese Ordner in der entsprechenden Reihenfolge anlegt. Zwar könnenwir uns eine Funktion vorstellen, die in einer Schleife die Einzelbestandteile derPfade ausgibt. Doch ist die Funktion dann doch etwas unhandlich, denn wirbenötigen ja eigentlich nicht die einzelnen Bestandteile, sondern eine Liste vonAusgaben dieser Form:

/etc/etc/examples/etc/examples/pl_sql/etc/examples/pl_sql/chap_2

Außerdem möchten wir mit diesen Daten anschließend eine Insert-Anweisungausstatten, die dann die einzelnen Verzeichnisse anlegt. Wie lösen wir ein sol-ches Problem? Vielleicht sollten wir eine Schleife schreiben, die die einzelnenWerte der Insert-Anweisungen berechnet und diese dann im Schleifendurchlaufaufruft. Das ist sicher eine Möglichkeit, doch hätte dies zur Folge, dass wir mehr-fach Insert-Anweisungen für einzelne Zeilen aufrufen. Schöner wäre, wir könn-ten eine Insert-Anweisung für alle Zeilen aufrufen. Eine bessere Variante wäre,

1452.book Seite 416 Donnerstag, 5. August 2010 3:55 15

Page 48: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

417

PL/SQL-Kollektionen 9.2

diese Informationen im Bulk an die Datenbank zu senden, wie wir dies inAbschnitt 9.2.2, »Massenverarbeitung mit assoziativen Tabellen«, erläuterthaben. Alternativ können wir dieses Verhalten aber auch mit einer Funktionerzeugen, die sich für die Insert-Anweisung wie eine Tabelle verhält und eineAnweisung der Form

insert into zieltabelleselect * from quelltabelle;

ermöglicht. Lassen Sie uns an diesem Beispiel einmal eine solche Funktion erstel-len. Zunächst einmal benötigen wir einen Rückgabewert der Funktion, der in derLage ist, eine Kollektion von Werten aufzunehmen. In unserem Beispiel wäre dasalso eine Tabelle von Zeichenketten. Wir erzeugen also zunächst diesen Rückga-betyp:

SQL> create type varchar_tab as table of varchar2(2000 char); 2 /Typ wurde erstellt.

Anschließend können wir eine Funktion deklarieren, die diesen Datentypzurückliefert und mit der Klausel pipelined zu einer Tabellenfunktion wird:

SQL> create or replace function get_sub_pathes( 2 path in varchar2) 3 return varchar_tab pipelined 4 as 5 begin 6 return; 7 end get_sub_pathes; 8 /Funktion wurde erstellt.

Listing 9.15 Grundgerüst einer Tabellenfunktion

Durch diese Deklaration ändern sich einige Dinge an der Art, die Funktion zuprogrammieren. Zunächst einmal enthält die Return-Klausel nun keinen Wertmehr, sondern steht allein, und zwar so, wie Sie das in Zeile 6 des Listings sehenkönnen. An den Stellen (typischerweise natürlich innerhalb einer Schleife), andenen die Funktion Werte zurückliefern soll, wird nun das Schlüsselwort piperow sowie der Rückgabewert in Klammern eingefügt. Durch diese Anweisungwird die Funktion die Werte an die aufrufende Umgebung zurückliefern. DerDatentyp, der zurückgeliefert wird, muss dabei dem Basistyp der Kollektion ent-sprechen. In unserem Fall ist dies also eine Zeichenkette bis 2000 Byte Länge.

1452.book Seite 417 Donnerstag, 5. August 2010 3:55 15

Page 49: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

418

Das Arbeiten mit Daten9

Sehen wir nun also die Funktion an, die unsere Zeichenkette in Einzelteile zer-schneidet und die Einzelteile an die aufrufende Umgebung zurückliefert:

SQL> create or replace 2 function get_sub_pathes(path in varchar2)

3 return varchar_tab pipelined 4 as 5 idx pls_integer := 1;

6 sub_path varchar2(2000); 7 begin 8 while idx > 0 loop

9 idx := instr(path, '/', idx + 1); -- ignore root slash 10 case idx 11 when 0 then sub_path := path;

12 else sub_path := substr(path, 1, idx - 1); 13 end case; 14 pipe row (sub_path); 15 end loop; 16 return; 17 end get_sub_pathes;

18 /Funktion wurde erstellt.

SQL> select column_value 2 from table( get_sub_pathes(

'/etc/examples/pl_sql/chap_2'));COLUMN_VALUE-----------------------------------------------------------------

/etc/etc/examples/etc/examples/pl_sql

/etc/examples/pl_sql/chap_2

Listing 9.16 Beispiel einer Tabellenfunktion

Wie Sie sehen, werden die Unterpfade als Zeichenkette während der Iterationenaus der Funktion heraus geliefert. Dies hat den Vorteil, dass der durch das Ergeb-nis allozierte Speicherbereich freigegeben und das Ergebnis durch die aufrufendeUmgebung weiterbearbeitet werden kann. In unserem Fall sammeln wir dieErgebnisse und fügen sie in einem Rutsch im Rahmen einer Insert-Anweisung ineine Tabelle ein. Beachten Sie in unserem Beispiel bei der nachfolgenden Abfragedie Verwendung des Konstruktors table(), der das Ergebnis der Funktion in

1452.book Seite 418 Donnerstag, 5. August 2010 3:55 15

Page 50: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

419

PL/SQL-Kollektionen 9.2

eine für SQL verwertbare Tabelle umformt. Bei dieser Umformung wird derRückgabewert in einer Tabelle mit dem Spaltennamen column_value überführt,der dann durch SQL abgefragt werden kann. Die Funktion ist im Übrigen auchein schönes Beispiel für die Verwendung einer While-Schleife, denn die Anzahlder Iterationen durch die Schleife ist nicht bekannt, sondern vom übergebenenParameter abhängig, andererseits aber auch gut außerhalb der Schleife überprüf-bar und daher besser als eine Exit-Klausel im Schleifenkörper.

Eine andere, sehr witzige Anwendung einer solchen Prozedur stellt die Verwen-dung als Bindevariable für Listen dar. Das Problem: Sie sollten Bindevariablenbenutzen, um eine SQL-Anweisung im Library-Cache der Datenbank wiederauf-findbar zu halten und dadurch die Anzahl der Parse-Vorgänge niedrig zu halten.Gut. Aber wie machen Sie das bei einer Anweisung wie der folgenden?

SQL> select * 2 from emp 3 where job in ('MANAGER', 'ANALYST');

Wie sollen Sie nun die Liste der Berufe als Bindevariable übergeben? Wenn eineVariable die Liste der Werte enthält, suchen wir auch nach einem Beruf, der soheißt wie die Liste der Berufe, die übergeben wird. Das geht also nicht. Stattdes-sen benötigen wir einen Weg, der SQL-Anweisung klarzumachen, dass eine Listevon Werten durchsucht werden soll. Die »beweglichen Teile«, die wir benötigen,um das Problem zu lösen, haben wir eigentlich schon programmiert, denn unsereTabellenfunktion von vorhin könnte nach einer kleinen Modifikation ja statteines wachsenden Pfades gern auch die einzelnen Ordnernamen ausgeben. Dannkönnten wir die Funktion im Kontext der obigen Abfrage wie eine Bindevariablefür Listenwerte nutzen, und zwar gleich auf zwei Arten:

select * from emp e, table(string_to_tab(csv_liste)) l

where e.job = l.column_value;

oder:

select * from emp where job in (select column_value

from table( string_to_tab(csv_liste)));

Dabei bestehen gute Chancen, dass der Optimizer der Datenbank beide Varian-ten mit dem gleichen Ausführungsplan belegt. Im obigen Pseudocode ist derParameter csv_liste eine Variable mit einer kommaseparierten Liste der einzel-

1452.book Seite 419 Donnerstag, 5. August 2010 3:55 15

Page 51: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

420

Das Arbeiten mit Daten9

nen Berufe, die durch die (neu zu schreibende) Tabellenfunktion string_to_tabin eine virtuelle Tabelle mit den Berufen umgebaut wird. Die Implementierungdieser neuen Funktion (vielleicht möchten Sie die Funktion auch gleich für Zah-len und Datumsangaben programmieren?) überlasse ich Ihnen als Übung. EinenHinweis hätte ich aber zu dieser Aufgabe noch: Das Umwandeln einer kommase-parierten Liste in eine assoziative Tabelle liefert Ihnen Oracle mit: Sehen Sie sicheinmal die Prozedur dbms_utility.comma_to_table an. Dann bliebe nur noch dieAusgestaltung als Tabellenfunktion.

Tabellenfunktionen werden laut Oracle-Dokumentation vor allem im Bereichvon Datenwarenhäusern empfohlen, um die Verarbeitung von Daten in Queueszu optimieren. Die Idee: Große Datenmengen werden durch eine Funktion itera-tiv verarbeitet und an die nächste Verarbeitungsstufe weitergegeben. Dadurchsinkt die Speicherbelastung, und es steigt die Fähigkeit zur Parallelisierung derAufgabe, weil andere Prozessoren die Teilergebnisse bereits verarbeiten können,während die Funktion noch an der vorhergehenden Stufe arbeitet. Das ist sicher-lich richtig, doch möchte ich den Einsatzbereich dieser Funktionen gern erwei-tern und Ihnen dieses Konzept auch für andere Aufgaben ans Herz legen. UmIhnen ein weiteres Einsatzfeld für solche Funktionen aufzuzeigen, programmie-ren wir uns einen Monatsgenerator, der in der Lage ist, eine beliebige AnzahlMonate ab einem Startmonat zu liefern. Beginnen wir also wieder mit einem Kol-lektionstyp für Datumsangaben:

SQL> create type date_tab as table of date; 2 /Typ wurde erstellt.

Nun folgt die Funktion. Sie erwartet ein Startdatum und eine Anzahl von Mona-ten, die erzeugt werden sollen:

SQL> create or replace function get_months ( 2 start_month in date, 3 month_amount in pls_integer) 4 return date_tab pipelined 5 as 6 begin 7 for i in 1 .. month_amount loop 8 pipe row (add_months(start_month, i)); 9 end loop; 10 return; 11 end get_months; 12 /Funktion wurde erstellt.

1452.book Seite 420 Donnerstag, 5. August 2010 3:55 15

Page 52: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

421

PL/SQL-Kollektionen 9.2

SQL> select column_value monat 2 from table( get_months( to_date('01.01.1980', 'dd.mm.yyyy'), 23));MONAT--------01.02.8001.03.80…01.12.8124 Zeilen ausgewählt.

Listing 9.17 Verwendung einer Tabellenfunktion als virtuelle Tabelle

Beachten Sie wiederum die Verwendung der Pseudospalte column_value in derSelect-Anweisung. Mithilfe dieser Funktion können Sie nun beliebig vieleMonate abrufen, ohne diese in einer Tabelle vorhalten zu müssen. Fragen Siesich, wozu eine solche Liste von Monaten gut sein soll? Nun, vielleicht benötigenSie eine Auswertung der Anzahl der Einstellungen in Ihr Unternehmen, grup-piert nach Monat. Was geschieht nun, wenn in einem Monat keine Mitarbeitereingestellt wurden? In diesem Fall würde kein Ergebnis für diesen Monat ausge-geben werden. Um dies aber zu erfahren, benötigen Sie eine Referenztabelle, diealle Auswertungsmonate enthält. Folgende, stark vereinfachte Auswertung könn-ten Sie also verwenden:

SQL> select d.column_value monat, 2 count(trunc(hiredate, 'MM')) einstellungen 3 from emp e right join 4 table( 5 get_months( 6 to_date('01.01.1980', 'dd.mm.yyyy'), 23)) d 7 on trunc(e.hiredate, 'MM') = d.column_value 8 group by d.column_value;MONAT EINSTELLUNGEN-------- -------------01.04.80 001.09.80 001.10.80 001.10.81 001.12.81 2…01.04.81 1

23 Zeilen ausgewählt.

Listing 9.18 Einsatz einer Tabellenfunktion

1452.book Seite 421 Donnerstag, 5. August 2010 3:55 15

Page 53: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

422

Das Arbeiten mit Daten9

Tabellenfunktionen verhalten sich also in gewisser Weise wie normale Daten-banktabellen, die in SQL-Abfragen verwendet werden können. Und sie haben essich wahrscheinlich schon gedacht: Daher rührt auch der Name. Weil aber Tabel-lenfunktionen darüber hinaus auch Kollektionen oder Cursor als Eingabeparame-ter akzeptieren, können sie in einem Workflow eingesetzt werden, in dem dieErgebnisse z.B. einer SQL-Abfrage iterativ an die Tabellenfunktion und von dortan eine weitere SQL-Anweisung weitergeben wird, und das ohne übermäßigeSpeicherbelastung, denn die kompletten Ergebnisse der Prozedur werden nie-mals materialisiert, sondern lediglich die einzelnen Teilergebnisse. Das folgendeBeispiel zeigt, wie die Ergebnisse einer Tabellenfunktion in eine weitere Tabel-lenfunktion gelangen und von dort in eine SQL-Anweisung geleitet werden.Allerdings liegen diese doch recht speziellen Einsatzgebiete etwas außerhalb desFokus dieses Buches, daher dient das folgende Beispiel eher der Demonstrationsolcher Konstrukte:

select * from table(f(cursor(select * from table(g()))));

Beachten Sie, wie durch den Konstruktor cursor() aus einer SQL-Ergebnismengeeine Cursor-Instanz generiert wird, die wiederum als Eingabeparameter derTabellenfunktion f genutzt werden kann.

Zum Schluss noch einen etwas obskur wirkenden Hinweis im Zusammenhangmit Tabellenfunktionen: Es gibt einen Fehler, der, so er denn auftritt, zwargeworfen wird, das Programm aber nicht zum Abbruch zwingt. Dieser Fehler hatden Namen no_data_needed und wird immer dann geworfen, wenn ein, in einerTabellenfunktion geöffneter, Cursor nicht komplett gelesen wird. Es führt wahr-scheinlich ein wenig zu weit, die Interna dieses Fehlers genauer zu beleuchten.Ich möchte lediglich aus dieser Tatsache den Tipp für Sie ableiten, zum Endeeiner Tabellenfunktion stets folgenden Exception-Handler zu schreiben:

exception when no_data_needed return;

Listing 9.19 Fehlerhandler in Tabellenfunktionen

Sie stellen mit diesem Fehlerhandler sicher, dass keine Speicherressourcen offen-gelassen werden und der Cursor der Tabellenfunktion unter allen Umständensauber geschlossen wird.

1452.book Seite 422 Donnerstag, 5. August 2010 3:55 15

Page 54: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

423

Mengenverarbeitung mit Cursorn 9.3

9.3 Mengenverarbeitung mit Cursorn

Die grundlegenden, syntaktischen Details zur Arbeit mit Cursoren haben wir unsja bereits in Abschnitt 7.4, »Kollektionen in PL/SQL«, angesehen. In diesemAbschnitt sollen nun Anwendungsbeispiele und weitergehende Konzepte folgen.Wir werden uns ansehen, auf welche Weise die zum Teil ja immens großenDatenmengen, die durch einen Cursor repräsentiert werden können, am bestenverwaltet werden.

9.3.1 Implizite versus explizite Cursor

Diskussionen unter PL/SQL-Fachleuten drehen sich zuweilen um die Frage, obein Cursor implizit oder immer explizit definiert und genutzt werden sollte. Ausmeiner Sicht handelt es sich bei der Diskussion eigentlich um zwei Diskussionen,denn einerseits bezieht sie sich darauf, ob stets ein Cursor definiert und abgefragtwerden solle oder eine SQL-Abfrage direkt in PL/SQL eingebunden werdensollte, andererseits darauf, ob die verkürzte Schreibweise einer Cursor-For-Schleife der expliziten Kontrolle eines Cursors mit open, fetch und close bevor-zugt werden sollte. Sehen wir uns beide Bereiche an: Ich nenne die erste Diskus-sion die Frage nach impliziten oder expliziten Cursorn, die zweite die Diskussionum implizite oder explizite Cursorkontrolle.

Implizite oder explizite Cursor

Um eine Tabellenzelle aus der Datenbank in eine PL/SQL-Variable umzukopie-ren, stehen im Grunde zwei Möglichkeiten zur Wahl. Einerseits können wireinen Cursor definieren, diesen explizit öffnen, eine Zeile herausholen und denCursor anschließend schließen. Dies wäre ein expliziter Cursor, denn wir habenden Cursor unter voller Kontrolle. Die Alternative wäre eine einfache Select-Into-Anweisung, die das Ergebnis direkt in eine PL/SQL-Variable kopiert. WelcherWeg ist besser?

Gerade in früheren Zeiten wurde der expliziten Methode deutlich der Vorzuggegeben. Der Grund: Bei der Verwendung eines impliziten Cursors kann die Feh-lermeldung too_many_rows auftauchen, wenn die Abfrage mehr als nur eine Zeilezurückliefert. Um diese Fehlermeldung zu erzeugen – so wurde argumentiert –,muss die Datenbank mindestens zwei Fetch-Operationen auf den impliziten Cur-sor durchführen, um die weitere Zeile zu lesen. Dieses Problem existiert beimexpliziten Cursor nicht, denn dort wird ja explizit gelesen. Zum Glück ist diesesArgument schon seit sehr langer Zeit nicht mehr stichhaltig: Bereits Version 7.1führte den Pre-Fetch-Mechanismus beim Lesen von Cursorn ein, eine ArtCaching, wie es auch beim Lesen von Festplatten etc. durchgeführt wird. Dieser

1452.book Seite 423 Donnerstag, 5. August 2010 3:55 15

Page 55: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

424

Das Arbeiten mit Daten9

Mechanismus liest ohnehin mehrere Zeilen in einem Durchgang vom Cursor undkann so auch den oben beschriebenen Fehler direkt aufdecken. Doch gibt es auchohne dieses Argument noch einige Pros und Contras, die wir uns im Folgendenetwas näher ansehen sollten.

Sehen wir uns die beiden Implementierungen im Vergleich einmal an:

SQL> declare 2 emp_id emp.empno%type; 3 begin 4 select empno 5 into emp_id 6 from emp 7 where ename = 'KING'; 8 exception 9 when no_data_found then raise; 10 when too_many_rows then raise; 11 end; 12 / PL/SQL-Prozedur erfolgreich abgeschlossen.

Und nun das Ganze explizit:

SQL> declare 2 cursor emp_cur (name in varchar2) is 3 select empno 4 from emp 5 where ename = name; 6 emp_id emp_cur%rowtype; 7 begin 8 open emp_cur('KING'); 9 fetch emp_cur into emp_id; 10 close emp_cur; 11 end; 12 /PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.20 Vergleich impliziter versus expliziter Cursor

Der Nachteil der impliziten Variante ist sicher die Verpflichtung, auftretendeFehler abfangen zu müssen. Insbesondere sind es zwei Fehler, die auftreten kön-nen: Es wird keine Zeile gefunden, oder es werden mehrere Zeilen gefunden.Diese Fehler müssen durch einen Exception-Block aufgefangen werden. Zwarließe sich die Abfrage gegen den Fehler too_many_rows dadurch schützen, dasszur Where-Klausel noch der Ausdruck and rownum = 1 hinzugefügt wird, um meh-

1452.book Seite 424 Donnerstag, 5. August 2010 3:55 15

Page 56: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

425

Mengenverarbeitung mit Cursorn 9.3

rere Zeilen zu unterdrücken; ein solcher Ausweg existiert jedoch für den Fehlerno_data_found nicht. Sie mögen sagen, es handele sich ja nun auch um Fehler,daher ist es richtig, diese im Fehlerbehandlungsteil zu behandeln, doch teile ichdiese Auffassung nur bedingt: Mir scheinen diese »Fehler« eher zu erwartendeAusnahmen zu sein, denn wenn ich z.B. einen Suchbegriff über eine Oberflächeeinfüge, kann es nun mal sein, dass ich zu diesem Begriff kein Ergebnis finde.Daher könnte mich dieser Fakt dazu zwingen, den impliziten Cursor in einenBegin-Exception-Block zu stecken, um die Ausführung der gesamten Prozedurnicht zu gefährden. Dies ist sicher ein Nachteil gegenüber dem expliziten Cursor,denn ein Fetch auf einen leeren (aber geöffneten!) Cursor hat keine Fehlermel-dung zur Folge, ebenso wenig wie das Öffnen eines Cursors mit leerer Ergebnis-menge.

Oft wird einem expliziten Cursor auch der Vorzug gegeben, weil er offensichtlicheffizienter eine Frage zu beantworten scheint als ein impliziter Cursor. Sehen wiruns stellvertretend einmal eine Existenzprüfung an. Bei diesem Problem sollgeprüft werden, ob in Abteilung 20 überhaupt Mitarbeiter arbeiten oder nicht.Ein erster Ansatz könnte also auf eine SQL-Anfrage herauslaufen wie etwa diese:

SQL> select count(*) anzahl 2 from emp 3 where deptno = 20; ANZAHL---------- 5

Doch wollen wir eigentlich gar nicht wissen, wie viele Mitarbeiter in der Abtei-lung arbeiten, sondern es reicht uns, zu wissen, dass mindestens ein Mitarbeiterdort arbeitet. Gerade bei großen Tabellen ist der Aufwand für die komplette Zäh-lung also unnötig teuer. Daher könnte uns folgender Code helfen:

SQL> declare 2 cursor emp_dept is 3 select 1 found 4 from emp 5 where deptno = 20; 6 emp_found emp_dept%rowtype; 7 begin 8 open emp_dept; 9 fetch emp_dept into emp_found; 10 close emp_dept; 11 if emp_found.found = 1 then 12 dbms_output.put_line('Mitarbeiter gefunden'); 13 end if;

1452.book Seite 425 Donnerstag, 5. August 2010 3:55 15

Page 57: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

426

Das Arbeiten mit Daten9

14 end; 15 /Mitarbeiter gefundenPL/SQL-Prozedur erfolgreich abgeschlossen.

Doch liegt hier der Fehler im SQL: Es ist einfach nicht der richtige Weg, eine Prü-fung auf Existenz über die Anweisung count(*) durchzuführen, dafür gibt es dasKonstrukt

SQL> select 1 found 2 from dual 3 where exists(select 1 4 from emp 5 where deptno = 20); FOUND---------- 1

und mithin die Möglichkeit, diese Abfrage implizit zu formulieren und direkt ineine lokale Variable umzukopieren. Zusammenfassend kann man es vielleicht soformulieren: Es ist nichts Falsches daran, einen Cursor explizit zu formulierenund zu benutzen. Dagegen spricht im Einzelfall wahrscheinlich die höhere Code-menge, die benötigt wird, um ihn zu deklarieren. Für explizite Cursor spricht dieFehlertoleranz. Es ist aber auch am Gegenteil nichts falsch, und wenn dadurchdie Menge des Codes reduziert wird, plädiere ich für die lesbarere Variante. ImÜbrigen ist es immer richtig, sich zunächst einmal darüber zu informieren, obeine gewisse Aussage nicht auch in SQL formuliert werden kann, denn dieserWeg ist eigentlich immer der beste.

Implizite oder explizite Cursorkontrolle

Cursor können, wie bereits besprochen, explizit über eine eigene Deklarationund die Behandlung über open, fetch und close gesteuert, oder aber im Rahmenvon Cursor-For-Schleifen implizit verwaltet werden. Dabei stellt sich die Frage,ob der eine Weg dem anderen vorzuziehen ist und welche Überlegungen ange-stellt werden sollten, um die Wahl zwischen den beiden Varianten zu treffen.

Zunächst einmal gibt es Fälle, in denen die Wahl nur durch einen expliziten Cur-sor erfüllt werden kann. Dies ist zum Beispiel dann der Fall, wenn der Cursornicht in einem Rutsch, sondern in mehreren, unabhängigen Teilschritten bear-beitet werden soll. Stellen wir uns dazu eine Funktion vor, die einen Cursor öff-net, die ersten 10 Zeilen des Cursors bearbeitet, anschließend eine andere Auf-gabe ausführt und dann weitere 10 Zeilen des Cursors abarbeitet. In diesem Fallist die Wahl relativ eindeutig, denn der Cursor einer Cursor-For-Schleife wird

1452.book Seite 426 Donnerstag, 5. August 2010 3:55 15

Page 58: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

427

Mengenverarbeitung mit Cursorn 9.3

beim Verlassen der Schleife implizit geschlossen und die Ergebnismenge verwor-fen. Zudem ist es schwierig oder zumindest unnötig aufwendig, eine Position imCursor gezielt »anzufahren«, um zum Beispiel dort fortzufahren, wo ein früheresÖffnen und teilweises Bearbeiten des gleichen Cursors geendet hat. Denken Sienur daran, dass zwei gleiche Abfragen nacheinander nicht das gleiche Ergebnisliefern müssen, um das Problem zu verstehen. Und selbst wenn die Abfragen dasgleiche Ergebnis liefern, ist nicht garantiert, dass die Daten in der gleichen Rei-henfolge geliefert werden, falls Sie keine explizite Sortierreihenfolge über eineOrder-By-Klausel vorgegeben haben. Ein explizit verwalteter Cursor ist demge-genüber einfach zu handhaben, denn die einmal erkannte Ergebnismenge bleibtkonstant, bis der Cursor geschlossen wird. Ich kann nun also ohne Schwierigkei-ten einen Cursor öffnen, eine Teilmenge verarbeiten, eine andere Arbeit ausfüh-ren und anschließend mit der Bearbeitung des Cursors fortfahren. Solche Fällesind gar nicht so selten, wie dies auf den ersten Blick erscheinen mag: Stellen wiruns vor, eine Ergebnismenge bestehe aus 250 Zeilen, die durch einen Cursor aufder Datenbank erkannt wurden. Davon werden 50 Zeilen an die Oberflächegesendet, und erst dann, wenn der Benutzer weitere Daten sehen möchte, for-dert er weitere Daten an. Dieser Fall könnte mit einem expliziten Cursor leichtumgesetzt werden. Ebenso wäre es in diesem Fall falsch, die Anfrage bei Neuan-forderung erneut auszuführen: Die große Zeitspanne, die zwischen der erstenund der zweiten Anfrage verginge, beinhaltete eine zu große Gefahr, unter-schiedliche Daten zu liefern.

Ebenso verhält es sich, wenn der Cursor als Cursorvariable von mehreren Funk-tionen bearbeitet werden soll. Auch hier ist die explizite Verarbeitung günstiger.Ganz besonders gilt das natürlich für Cursorvariablen, die über Systemgrenzenhinweg genutzt werden sollen. Diesen speziellen Fall werden wir im nächstenAbschnitt gesondert betrachten.

Keine Entscheidungshilfe kommt im Übrigen aus Überlegungen zur Performanzdes einen oder anderen Cursortyps: Beide Cursor sind im Großen und Ganzengleich schnell. Das hat seinen Grund darin, dass Oracle im Laufe der Jahre großeAnstrengungen unternommen hat, die Arbeit mit Cursorn einfach und intuitiv zugestalten. Daher sollte aus meiner Sicht folgende Empfehlung gelten: VerwendenSie implizit verwaltete Cursor, solange kein wichtiger Grund gegen diese Typenspricht. Implizite Cursor sind leichter zu schreiben und zu verstehen, genausoschnell, und die Gefahr, einen Cursor unbeabsichtigt geöffnet zu lassen unddadurch Speicherlecks zu riskieren, besteht nicht.

Wo wir allerdings gerade dabei sind: PL/SQL kennt derzeit noch keinen Befehl,der dem Finally-Block in Java entspräche, also einem Block, der in jedem Fall,

1452.book Seite 427 Donnerstag, 5. August 2010 3:55 15

Page 59: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

428

Das Arbeiten mit Daten9

auch bei Auftreten eines Fehlers, ausgeführt wird. Daher liegt es bei der Verwen-dung expliziter Cursor in Ihrer Verantwortung, Cursor im Fehlerfall zu schließen.Hierzu bietet sich natürlich zum Beispiel der Exception-Block an. Achten Sie aberdarauf, dass alle abgefangenen Fehler auch die offenen Cursor schließen. Aller-dings: Cursor, die innerhalb einer Funktion oder Prozedur definiert wurden,werden, wie alle anderen lokalen Variablen auch, nach Verlassen der Prozedurauch wieder gelöscht. Daher bezieht sich der Hinweis auf Cursor, die z.B. aufPackage-Ebene definiert wurden und ihre Ergebnismenge für die gesamte Daten-banksession behalten.

Ein eher ästhetisches Argument sei noch einmal wiederholt: Da die Deklarationeines Cursors irgendwann auf einer SQL-Anweisung beruht, muss diese Anwei-sung irgendwo hinterlegt werden. Dabei bieten sich mehrere Möglichkeiten an:

� in einer Cursor-For-SchleifeDieser Weg ist aus meiner Sicht nur für sehr kurze SQL-Anweisung anwend-bar, längere SQL-Anweisungen stören das Verständnis der Schleife doch sehr.

� in einer Cursordeklaration im Deklarationsabschnitt der ProzedurDieser Ansatz erscheint mir für kurze bis mittlere SQL-Anweisungen dann inOrdnung, wenn insgesamt relativ wenige Cursor in der Anwendung verwen-det werden oder die Cursor nur von internem Interesse für die Funktion oderProzedur sind.

� in einem PackageBei diesem Ansatz werden die Cursor in einem Package gesammelt und dortim Package-Körper deklariert. Dieses Verfahren bietet sich als zentrale Sam-melstelle für SQL-Anweisungen für einen Funktionsbereich an, wenn dieseAnweisungen nicht nur interne Bedeutung haben.

� als Views in der DatenbankDies ist sicher der komfortabelste Weg, denn in diesem Umfeld können Siedie Anweisungen jederzeit testen, ohne die beteiligten Funktionen oder Pro-zeduren aufrufen zu müssen. Zudem sind Views gut zu warten und zu doku-mentieren. Dieser Ansatz hat seine Schwächen, wenn das Datenbankschemarelativ offen für andere Benutzer ist, da durch die Views eventuell Implemen-tierungsdetails offengelegt werden könnten, die in Packages besser zu verber-gen sind. Allerdings sind SQL-Anweisungen fast nicht zu verbergen: Spätes-tens beim Tracen der Session werden alle SQL-Anweisungen sichtbar, sodassdieses Argument möglicherweise nicht stichhaltig ist.

Für welche Variante Sie sich auch entscheiden, wichtig ist, dass Sie eine bewussteEntscheidung fällen. Je umfangreicher das Projekt ist, umso bedeutender werden

1452.book Seite 428 Donnerstag, 5. August 2010 3:55 15

Page 60: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

429

Mengenverarbeitung mit Cursorn 9.3

diese Entscheidungen. Zur Cursor-For-Schleife noch eine Anmerkung: DieseSchleifen können ja in den beiden Formen

for rec in cur loop … end loop;

oder

for rec in (SQL-Anweisung) loop … end loop;

geschrieben werden. Gerade bei der zweiten Schreibweise steht uns allerdingskein Cursorattribut zur Verfügung, denn nach dem Verlassen der Schleife gibt eskeinen Cursor mehr. Daher müssen Sie auf alternative Wege achten, wie Sie z.B.die Anzahl der verarbeiteten Zeilen ausgeben möchten. Hier bietet sich z.B. einecount-Variable an oder die Inklusion der Pseudospalte rownum in die SQL-Abfrage(Achtung, wenn Sie die Ergebnismenge sortieren möchten!).

9.3.2 Top-N-Analyse

Auch wieder mal eines dieser Buzzwords! Unter einer Top-N-Analyse verstehtman schlicht die Abfrage der besten n-Zeilen gemäß einem Sortierkriterium: dieTop-5-Verdiener, die drei besten Produkte, die fünf schönsten Mädchen. Bei derAbfrage solcher Rangfolgen ist es natürlich zunächst einmal erforderlich, dieErgebnismenge zu sortieren. Dann aber scheiden sich die Geister: Wie soll dieAbfrage durchgeführt werden? Zur Wahl stehen mindestens die folgenden bei-den Wege:

SQL> set serveroutput on;SQL> declare 2 cursor top_earner is 3 select empno, ename, sal 4 from emp 5 order by sal desc; 6 employee top_earner%rowtype; 7 begin 8 open top_earner; 9 for i in 1 .. 5 loop 10 fetch top_earner into employee; 11 dbms_output.put_line( 12 'Rang ' || i || ': ' || employee.ename); 13 end loop; 14 end; 15 /Rang 1: KINGRang 2: FORD

1452.book Seite 429 Donnerstag, 5. August 2010 3:55 15

Page 61: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

430

Das Arbeiten mit Daten9

Rang 3: SCOTTRang 4: JONESRang 5: BLAKEPL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.21 Für Ihr Buzzwords-Vokabular: Eine Top-N-Analyse

Oder aber folgende Variante, die sich eigentlich nur im SQL unterscheidet:

SQL> declare 2 cursor top_earner is 3 select * 4 from (select empno, ename, sal 5 from emp 6 order by sal desc) 7 where rownum < 6; 8 employee top_earner%rowtype; 9 begin 10 open top_earner; 11 fetch top_earner into employee; 12 while top_earner%found loop 13 dbms_output.put_line( 14 'Rang ' || top_earner%rowcount || 15 ': ' || employee.ename); 16 fetch top_earner into employee; 17 end loop; 18 end; 19 /Rang 1: KINGRang 2: SCOTTRang 3: FORDRang 4: JONESRang 5: BLAKEPL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.22 Top-N-Analyse, Alternative 2

Lassen Sie sich ein wenig Zeit, um sich den Unterschied zwischen beiden Imple-mentierungen klarzumachen. Die Frage reduziert sich letztlich auf folgende: Wel-che SQL-Anfrage ist besser? Auf den ersten Blick scheint klar zu sein, dass derUnterschied nur marginal ausfallen wird, denn schließlich müssen beide Anwei-sungen die gesamte Tabelle emp durchsuchen und die besten Verdiener finden.Im Zweifel ist die erste Verwendung zumindest kürzer, und da das SQL einfachererscheint, sollte diese Variante das Mittel der Wahl sein. Doch ist genau das

1452.book Seite 430 Donnerstag, 5. August 2010 3:55 15

Page 62: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

431

Mengenverarbeitung mit Cursorn 9.3

Gegenteil der Fall: Die zweite Implementierung ist, zumal bei sehr vielen Zeilenin emp, drastisch schneller! Woran liegt das?

Oracle kann im zweiten Fall einen besonderen Algorithmus verwenden, der imersten Fall nicht offensichtlich ist: Da die Datenbank weiß, dass Sie sich nur fürdie besten n Verdiener interessieren, kann sie eine Optimierung anwenden, dieim Ausführungsplan als Order by Stopkey bezeichnet wird. Bei diesem Verfahrenwird die Datenbank die zufällig ersten fünf Zeilen der Tabelle lesen und sortieren.Es wird in dieser Gruppe einen Mitarbeiter geben, der am wenigsten verdient,sagen wir, 1250 Taler. Dieses Gehalt wird nun mit dem Gehalt des 6. Mitarbeitersder Tabelle verglichen. Ist es höher, wird die 6. Zeile ignoriert und die nächsteZeile verglichen. Lediglich dann, wenn ein Mitarbeiter mehr als diese 1250 Talerverdient, muss er in die Riege der besten 5 Mitarbeiter aufgenommen werden,ansonsten kann der Datensatz ignoriert werden. Anschließend kann die Suchemit dem nun fünftbesten verdienenden Mitarbeiter fortgesetzt werden. Beim ers-ten Ansatz wird die Datenbank im Gegensatz hierzu gezwungen, die gesamteTabelle zu sortieren, obwohl nachher lediglich die ersten 5 Zeilen dieser sortiertenMenge abgefragt werden. Daher muss die gesamte Tabelle auch im UGA der Ses-sion gehalten werden (dort liegen die Sortierbereiche einer Session) und nicht nurdie fünf Zeilen, auf die es ankommt. Und dies noch abgesehen von dem einge-sparten Aufwand, auch noch den 317.-besten Verdiener sortieren zu müssen.

Man hätte eigentlich drauf kommen können, nicht? Andererseits ist das eines dervielen Beispiele dafür, dass Sie der Datenbank sagen sollten, was Sie von ihr wol-len, damit die Datenbank auch etwas für Sie tun kann. Gerade gestandene Anwen-dungsentwickler tendieren meiner Beobachtung zufolge dazu, der Datenbank»helfen« zu wollen, den richtigen Weg zu finden. Ich habe häufig die ernüchterndeErfahrung machen dürfen, dass die Datenbank meistens besser weiß, was für siegut ist, als ich. Daher tendiere ich dazu, der Datenbank die Entscheidung zu über-lassen, solange ich keinen starken, nachweisbaren Grund habe, dies nicht zu tun.Und natürlich ist das wieder einmal ein Argument für die Empfehlung, sich mitdem SQL der Datenbank auseinanderzusetzen, gegen die man programmiert.

Als Anmerkung zu dieser Abfrage: Vielleicht noch etwas schneller geht die Suchemit einer Abfrage über eine analytische Funktion. Hier können wir uns dieAbfrage z.B. so vorstellen:

select * from (select empno, ename, sal, rank() over (order by sal desc) rang from emp) where rang < 6;

Listing 9.23 Top-N-Analyse, Alternative 3

1452.book Seite 431 Donnerstag, 5. August 2010 3:55 15

Page 63: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

432

Das Arbeiten mit Daten9

Diese analytische Funktion ist noch einmal gegenüber der besseren Abfrage vonvorhin optimiert und daher eventuell (bitte testen!) noch einmal schneller. Wich-tig ist mir aber: Sagen Sie der Datenbank, was Sie von ihr wollen, dann kann dieDatenbank auch etwas für Sie tun.

9.3.3 Cursorvariablen (REF-Cursor)

Eine Cursorvariable ist eine Variable, die auf einen Cursor zeigt. Dieser Variab-lentyp wird verwendet, um auf eine Ergebnismenge zu zeigen, ohne diese tatsäch-lich zu beinhalten. Durch die Trennung von Cursorvariable und Cursor ergebensich viele neue Möglichkeiten, die für die Programmierung von grundlegendemInteresse sind:

� Zunächst erhalten Sie mit einer Cursorvariablen die Möglichkeit, Cursor alsParameter an Prozeduren zu übergeben oder von dort als Ausgabeparameteroder Funktionsrückgabetyp zu erhalten.

� Dann können Cursorvariablen auf beliebige Cursor zeigen. Dadurch ergibtsich die Möglichkeit, beliebige Abfrageergebnisse durch eine einzige Methodeverarbeiten zu lassen.

� Mehrere Variablen können auf denselben Cursor zeigen, unabhängig davon,wo sie deklariert sind. Auf diese Weise können z.B. Clientanwendungen aufCursor zeigen, die auf dem Server liegen. Diese Cursor müssen also nicht kom-plett zum Client übertragen werden, sondern es werden lediglich dann Datenzum Client übertragen, wenn sie angefordert werden.

Cursorvariablen werden als Typ definiert und anschließend genutzt, indem eineVariable dieses Typs deklariert wird. Das folgende Beispiel definiert eine soge-nannte schwache Cursorvariable mit dem Namen my_cur. Schwach ist diese Cur-sorvariable in Hinblick auf ihre Typsicherheit, weil die Struktur der Ergebnis-menge nicht bekannt ist. Diese Variable kann allerdings beliebige Cursorrepräsentieren und ist damit sehr flexibel einsetzbar. Doch kann PL/SQL natür-lich erst zur Laufzeit prüfen, ob die folgenden Zuweisungen auf Variablen etc.überhaupt gültig sind. Hier also der Code für diese Cursorvariable:

declare type my_cur_t is ref cursor; my_cur my_cur_t;…

Sie kennen die grundsätzliche Vorgehensweise bereits aus der Arbeit mit Recordsoder assoziativen Tabellen.

Im Gegensatz zu diesem schwachen Cursor steht die starke Cursorvariable, beider zum Zeitpunkt der Deklaration bereits die Struktur des Cursors festgelegt

1452.book Seite 432 Donnerstag, 5. August 2010 3:55 15

Page 64: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

433

Mengenverarbeitung mit Cursorn 9.3

wird. Zwar kann diese Cursorvariable immer noch beliebige Cursor repräsentie-ren, doch haben diese Cursor alle die gleiche vordefinierte Struktur. Auf dieseWeise kann bereits zur Erstellungszeit geprüft werden, ob die nachfolgendenManipulationen mit diesem Cursor machbar sind oder nicht. Sehen wir uns auchhierzu ein Beispiel an:

declare type my_strong_cur_t is ref cursor return emp%rowtype; my_strong_cur my_strong_cur_t;…

Beiden Cursorvariablentypen ist gemeinsam, dass die Arbeit mit Ihnen weitge-hend der mit einem »normalen« Cursor entspricht. Es stehen die gleichen Cursor-Attribute zur Verfügung: Auch hier wird über ein fetch eine Zeile geliefert undüber die Anweisung close der (durch die Cursorvariable repräsentierte) Cursorgeschlossen. Allerdings muss die Open-Anweisung für Cursorvariablen geändertwerden, denn es muss ja irgendwann definiert werden, wie der Cursor, derdurch diese Variable repräsentiert wird, definiert sein soll. Dies geschieht, indemdie Open-Anweisung durch die For-Klausel erweitert und mit einer SQL-Abfragespezifiziert wird. Sehen wir uns hierzu ein Beispiel an:

SQL> declare 2 type my_strong_cur_t is ref cursor return emp%rowtype; 3 my_strong_cur my_strong_cur_t; 4 my_rec my_strong_cur%ROWTYPE; 5 begin 6 open my_strong_cur for 7 select * 8 from emp 9 where deptno = 10; 10 loop 11 fetch my_strong_cur into my_rec; 12 exit when my_strong_cur%NOTFOUND; 13 dbms_output.put_line(my_rec.ename || 14 ' arbeitet als ' || my_rec.job); 15 end loop; 16 close my_strong_cur; 17 end; 18 /CLARK arbeitet als MANAGERKING arbeitet als PRESIDENTMILLER arbeitet als CLERK

PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.24 Verwendung einer stark typisierten Cursor-Variablen

1452.book Seite 433 Donnerstag, 5. August 2010 3:55 15

Page 65: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

434

Das Arbeiten mit Daten9

Achten Sie bitte darauf, dass Sie, wenn Sie eine schwache Cursorvariable verwen-den, selbst dafür verantwortlich sind, keine Laufzeitfehler durch unmöglicheZuweisungen im Code zu erhalten. PL/SQL löst bei einer solchen unmöglichenZuweisung die Fehlermeldung ROWTYPE_MISMATCH aus.

Wir können, wie bereits angesprochen, eine Cursorvariable als Parameter einerMethode oder auch als Rückgabetyp einer Funktion deklarieren. Allerdings stelltsich dabei ein Problem: Wir haben ja gesehen, dass eine Cursorvariable als Typdeklariert und anschließend von diesem Typ abgeleitet werden muss. Dies stelltsich für eine Methode als sehr schwierig heraus, denn dort muss ein Parameter-typ explizit angegeben werden. Folgender Versuch schlägt also fehl:

SQL> create or replace procedure my_cursor_proc 2 (cur_in in ref cursor) 3 as

4 begin 5 null; 6 end;

7 /Warnung: Prozedur wurde mit Kompilierungsfehlern erstellt.SQL> show errors

Fehler bei PROCEDURE MY_CURSOR_PROC:LINE/COL ERROR-------- -----------------------------------------------------

0/0 PL/SQL: Compilation unit analysis terminated2/18 PLS-00201: Bezeichner 'CURSOR' muss deklariert werden

Listing 9.25 Versuch, eine Cursorvariable als Parameter zu übergeben

Andererseits können wir die Typdeklaration und die Ableitung einer Variablenin einer Parameterdeklaration nicht unterbringen. Welche Auswege bieten sichan? Zunächst einmal ist es zwar grundsätzlich möglich, Typen in SQL zu definie-ren, doch auch dieser Weg schlägt bei einer Cursorvariablen fehl, denn eine Cur-sorvariable kennt SQL nicht:

SQL> create type refcur is ref cursor; 2 /

create type refcur is ref cursor;*FEHLER in Zeile 1:

ORA-21561: OID-Generierung nicht erfolgreich

1452.book Seite 434 Donnerstag, 5. August 2010 3:55 15

Page 66: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

435

Mengenverarbeitung mit Cursorn 9.3

Oracle versucht, einen SQL-Objekttyp zu erzeugen, und das gelingt nicht. EinAusweg ist die Verwendung eines Packages. Dies ist einer der vielen Vorteile vonPackages. In einer Package-Spezifikation können wir einen Typ in PL/SQL ver-wenden und diesen anschließend im Prozeduraufruf verwenden. In der Package-Spezifikation können sowohl schwache als auch starke Cursorvariablen deklariertwerden. Analog gehen Sie vor, wenn Sie eine Funktion deklarieren, die einenCursor als Rückgabewert definiert:

SQL> create or replace package cursor_pkg

2 as 3 type refcur is ref cursor; 4 procedure my_cursor_proc (cur_in in refcur);

5 function my_cursor_func (sql_stmt in varchar2) 6 return refcur; 7 end cursor_pkg;

8 /Package wurde erstellt.

Listing 9.26 Erste Variante: Implementierung als Package-Cursor

Ein anderer Weg ist die Verwendung eines vordefinierten Cursortyps in SQL: dessys_refcursor. Dieser Cursor kann allerdings nur als schwacher Cursortyp ver-wendet werden, wie im folgenden Beispiel gezeigt:

SQL> create or replace procedure my_cursor_proc( 2 cur in sys_refcursor)

3 as 4 begin 5 null;

6 end my_cursor_proc; 7 /Prozedur wurde erstellt.

SQL> show errorsKeine Fehler.

Listing 9.27 Zweite Variante: Verwendung von »sys_refcursor«

9.3.4 Cursor-Ausdrücke

Eine weitere Variante der Verwendung von Cursorn sind die Cursor-Ausdrücke.Stellen wir uns hierzu vor, Sie müssten für eine Auswertung eine hierarchischeListe erstellen, in der die Mitarbeiter pro Abteilung aufgeführt werden sollen.

1452.book Seite 435 Donnerstag, 5. August 2010 3:55 15

Page 67: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

436

Das Arbeiten mit Daten9

Der Bericht soll in PL/SQL erstellt werden. Nun könnten Sie die Aufgabe durchzwei Cursorn lösen: einen für jede Abteilung und einen für die Mitarbeiter derAbteilung. Sie haben aber auch die Möglichkeit, einen einzigen Cursor mit einemeingeschachtelten Cursor zu verwenden. Dazu können Sie in SQL eine harmoni-sierte Unterabfrage als Cursor deklarieren und die dadurch erzeugte Ergebnis-menge durch geschachtelte Loop-Anweisungen durchlaufen. Wir sparen unsdadurch mehrere Roundtrips zum Server und verwalten die verschiedenen Cur-sor und deren Beziehungen untereinander implizit in einer Struktur.

Die Benutzung solcher Cursor-Ausdrücke ist also ein zweistufiger Prozess.Zunächst müssen die geschachtelten Cursor in SQL erzeugt werden. Sehen wiruns eine solche Abfrage einmal an:

select dname, loc, cursor(select job, cursor(select ename from emp n where n.job = e.job) from emp e where e.deptno = d.deptno) from dept d

Sie erkennen die harmonisierten Unterabfragen, die durch die Funktioncursor() zu eingeschachtelten Cursorn deklariert werden. Anschließend kannder Bericht erzeugt werden, indem drei ineinander geschachtelte Loop-Anwei-sungen die Cursor bearbeiten. Zur Bearbeitung der oben gezeigten Anweisungerstellen wir uns eine Prozedur, die einen Bericht ausgibt:

SQL> create or replace procedure print_employee_report

2 as 3 type refcur is ref cursor; 4 department_cur refcur;

5 employee_cur refcur; 6 sql_stmt varchar2(400 char) := 7 'select initcap(dname), initcap(loc),

8 cursor(select initcap(ename), initcap(job) 9 from emp e 10 where e.deptno = d.deptno)

11 from dept d'; 12 dept_name dept.dname%TYPE; 13 dept_location dept.loc%TYPE;

14 job emp.job%TYPE; 15 name emp.ename%TYPE; 16 begin

1452.book Seite 436 Donnerstag, 5. August 2010 3:55 15

Page 68: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

437

Mengenverarbeitung mit Cursorn 9.3

17 open department_cur for sql_stmt; 18 loop 19 fetch department_cur

20 into dept_name, dept_location, employee_cur; 21 exit when department_cur%NOTFOUND; 22 dbms_output.put_line(

23 'Abteilung ' || dept_name || 24 ' in ' || dept_location);

25 loop 26 fetch employee_cur 27 into name, job;

28 exit when employee_cur%NOTFOUND; 29 dbms_output.put_line( 30 'Name: ' || name || ', Beruf: ' || job );

31 end loop; 32 dbms_output.put_line(' '); 33 end loop;

34 close department_cur; 35 end print_employee_report; 36 /

Prozedur wurde erstellt.

SQL> exec print_employee_report;

Abteilung Accounting in New YorkName: Clark, Beruf: ManagerName: King, Beruf: President

Name: Miller, Beruf: Clerk

Abteilung Research in Dallas

Name: Smith, Beruf: ClerkName: Jones, Beruf: ManagerName: Scott, Beruf: Analyst

Name: Adams, Beruf: ClerkName: Ford, Beruf: Analyst

Abteilung Sales in ChicagoName: Allen, Beruf: SalesmanName: Ward, Beruf: Salesman

Name: Martin, Beruf: SalesmanName: Blake, Beruf: ManagerName: Turner, Beruf: Salesman

Name: James, Beruf: Clerk

1452.book Seite 437 Donnerstag, 5. August 2010 3:55 15

Page 69: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

438

Das Arbeiten mit Daten9

Abteilung Operations in Boston

PL/SQL-Prozedur erfolgreich abgeschlossen.

Listing 9.28 Verwendung von Cursor-Ausdrücken

Bitte beachten Sie, dass diese Konstruktion auf Cursorvariablen angewiesen ist,um die in SQL erstellten Cursor mit einem Handler zu versehen, mit dem in PL/SQL gearbeitet werden kann. Daher deklariere ich zunächst zwei Cursorvariab-len, denen anschließend die geschachtelten SQL-Cursor zugewiesen werden.Außerdem habe ich noch einige Variablen zur Aufnahme der Spaltenwerte dekla-riert. In Zeile 18 und 25 erkennen Sie die beiden geschachtelten Loop-Anweisun-gen. Die Zuweisung des in der SQL erzeugten geschachtelten Cursors zur Cursor-variablen employee_cur erfolgt innerhalb der inneren Schleife durch die Fetch-Anweisung in Zeile 26.

Cursor-Ausdrücke eignen sich insbesondere beim Verschachteln mehrerer Tabel-len, die zueinander in einer 1:n-Beziehung stehen. In diesem Kontext könnenCursor-Ausdrücke implizit die Steuerung der geschachtelten Cursor überneh-men. Im Beispiel oben ist lediglich der employee_cur als geschachtelter Cursorbeteiligt, doch lassen sich auch beliebig tief geschachtelte Konstruktionen den-ken. Natürlich geht solches SQL zulasten der Lesbarkeit, doch muss man anderer-seits sagen, dass die Verarbeitung dieser Cursor eher klar ist als das herkömmli-che Pendant. Zudem ist diese Schachtelung schneller, weil sie vollständig auf derSQL-Seite durchgeführt werden kann. Geschlossen wird zum Ende der Bearbei-tung lediglich der äußere Cursor. Dadurch werden implizit auch die geschachtel-ten Cursor freigegeben.

Es ist ganz interessant, sich einmal die Ausgabe der SQL-Anweisung anzu-schauen, die durch die Cursor-Ausdrücke erzeugt wird. Dadurch wird eventuellklarer, auf welche Weise die einzelnen Cursor ineinandergeschachtelt sind:

SQL> select initcap(dname) dname, 2 initcap(loc) loc, 3 cursor(select initcap(ename) ename, 4 initcap(job) job 5 from emp e 6 where e.deptno = d.deptno) emp_cur 7 from dept d;DNAME LOC EMP_CUR-------------- ------------- --------------------Accounting New York CURSOR STATEMENT : 3

CURSOR STATEMENT : 3

1452.book Seite 438 Donnerstag, 5. August 2010 3:55 15

Page 70: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

439

Mengenverarbeitung mit Cursorn 9.3

ENAME JOB---------- ---------Clark ManagerKing PresidentMiller Clerk

Research Dallas CURSOR STATEMENT : 3

CURSOR STATEMENT : 3ENAME JOB---------- ---------Smith ClerkJones ManagerScott AnalystAdams ClerkFord Analyst

Sales Chicago CURSOR STATEMENT : 3

CURSOR STATEMENT : 3ENAME JOB---------- ---------Allen SalesmanWard SalesmanMartin SalesmanBlake ManagerTurner SalesmanJames Clerk

6 Zeilen ausgewählt.

Operations Boston CURSOR STATEMENT : 3

CURSOR STATEMENT : 3Es wurden keine Zeilen ausgewählt

Listing 9.29 Darstellung eines Cursor-Ausdrucks in »SQL*Plus«

Die Cursor-Funktion wirkt wie eine Gruppenfunktion, erzeugt allerdings keineeinzelne Zahl, sondern einen strukturierten Typ aus mehreren Zeilen, deranschließend als Cursor interpretiert und von PL/SQL gelesen werden kann. Alsalternative Sicht sehen Sie in Abbildung 9.2, wie der SQL-Developer einen sol-chen Cursor-Ausdruck darstellt.

1452.book Seite 439 Donnerstag, 5. August 2010 3:55 15

Page 71: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

440

Das Arbeiten mit Daten9

Abbildung 9.2 Darstellung eines Cursor-Ausdrucks in SQL-Developer

1452.book Seite 440 Donnerstag, 5. August 2010 3:55 15

Page 72: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

865

Index

A

Abfragegenerator 197Abhängigkeitskette 396

Änderung der Spaltendeklaration 397Änderung des Datentyps 397

Access Control List (ACL) 654, 671, 719, 749, 857

Advanced Queueing (AQ) 27, 29, 288, 478, 481, 743, 859

Advisory 244Analytische Funktion 210, 548anonymer PL/SQL-Block 250, 253, 269Anwendungsarchitektur 22, 181Apache 238Apache Tomcat 239Application Development Framework (ADF)

237Application Express (APEX) 37, 86, 223,

237, 749, 792APEX-Listener 239

Applikationsserver 85, 206Arbeiten mit Daten 23Arbeiten mit großen Datenstrukturen 24Arbeiten mit XML 25Architektur einer Applikation 96, 98Archive-Log-Modus 64ASCII 836ASM 573Assoziative Tabelle 314, 407, 446, 462,

519, 576Count-Funktion 314Delete-Funktion 315Exists-Funktion 314First/Last-Funktion 315Prior/Next-Funktion 315

Atomizität 346, 351Auditierung 243, 375

Fine Grained Auditing (FGA) 245Ausführungsplan 110Ausführungsrechte von PL/SQL-Blöcken

276Ausgabeparameter 258Ausnahme � Exception

Authid-KlauselAufruferrecht 277, 768Aufrufrecht 277Eigentümerrecht 276, 277

AutoCommit 172, 726Automatic Database Diagnostic Monitor

(ADDM) 479Automatic Segment Space Management

(ASSM) 573autonome Transaktion 279, 346, 862Autotrace 43Autowert 116

B

Backup & Recovery 95, 98, 104, 167, 244, 480

Base64-Kodierung 106bedingte Anweisung 252Beispieldatenbank 35Beispielskripte 52Benutzerdefinierte Typen 120Benutzerprofil 168Benutzerverwaltung 92Best Practice

Aufrufsystematik von Prozedurparametern 265

Benennungskonvention 389Case- versus If-Anweisung 295Case-Anweisung 292Definition von Prozedurparametern 265Funktion mit Ausgabeparameter 268kaskadierende Trigger 353Maskierung von Variablen 255Schema & Tablespace 98Speicherung von XML in der Datenbank

611, 614Übergabe von Parametern mit Records 403Verwendung von Blocktypen 281Verwendung von SQL 517Wahl eines Schleifentyps 304XML-Datenbank 669

Binary Large Objects (BLOB) 77Bindevariable 164, 174, 195

1452.book Seite 865 Donnerstag, 5. August 2010 3:55 15

Page 73: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

866

Index

BLOB � DatentypBuchtipp

Effective Oracle Security by Design 35Mastering Oracle PL/SQL 35, 46Thomas Kyte 34

C

Change Data Capture (CDC) 478, 481Character Set Scanner 125Check-Summe 154CLOB � DatentypCode Smell 747Code-Generator 780Connection Pool 759Constraint 138, 205, 225, 233

Check 141, 233, 369Fremdschlüssel 141, 143, 146Primärschlüssel 346Unique Constraint 142, 149

Cursor 164, 316, 445, 751Attribut 319Caching 319Cursor-Ausdruck 435Cursor-For-Schleife 323Cursorvariable 328, 432Definition 316expliziter Cursor 423impliziter Cursor 423Kontrolle des Cursorzustandes 426Lesen 318Öffnen 317parametrierter Cursor 322schließen 319schwache Cursorvariable 432starke Cursorvariable 432Top-N-Analyse 429verteilter Cursor 753

D

Data Access Layer (DAL) 759, 775Data Dictionary 175Data Warehouse 97, 103, 107Database Access Descriptors (DAD) 239Database Change Notification (DCN) 156,

158, 741Database Configuration Assistant (DBCA)

654

Database Control 253Database Link 84Database Resident Connection Pool (DRCP)

78, 81, 84Verwaltung 83

Data-Modeler 41Dateisystem in der DB 119Datenbank als Datenframework 748Datenbankadministrator 98Datenbank-Alert 244Datenbankbenutzer 88, 759Datenbank-Constraint � ConstraintDatenbank-Konfigurationsassistent 123Datenbank-Link 117Datenbankobjekt � Oracle-DatenbankDatenbanktrigger � TriggerDatenframework 182, 203

Datenmodelländerung 208Integration von SQL und PL/SQL 208Mächtigkeit von SQL 209Performanz 204Sicherheitsdomäne 205Skalierbarkeit 205syntaktische Prüfung von SQL 208

Datenintegrität 138, 205, 367, 760Datenkonsistenz 22, 127, 137, 146, 150,

181, 182, 188, 225, 747, 753Dead Lock 146, 152explizites Sperren 150Latch 166Lock 165Lock-Escalation 166Lost Update 151optimistisches Sperren 153, 157pessimistisches Sperren 153, 155, 157Sperrmechanismus 165Sperrstrategie 157

Datenpumpe 181, 205Datenschutz 194, 753Datensicherheit 22, 97, 127, 166, 181, 182,

746Denial of Service Attack 168

Datensicht 113, 203, 204, 206, 257, 358, 445, 765Check-Option 358materialisierte Datensicht 113materialisierte Sicht 521, 525Materialized View 113user_source 468

1452.book Seite 866 Donnerstag, 5. August 2010 3:55 15

Page 74: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

867

Index

Datentyp 223, 249, 251, 258, 282Ableitung aus dem Data Dictionary 288abweichende Datentypen 286ANSI, DB/2 und SQL-DS 283Any 284anydata 481anydataset 481anytype 481Assoziative Tabelle 288Basistypen und Subtypen in PL/SQL 284benutzerdefinierter Datentyp 283, 288BFILE 559, 576BLOB 559, 576boolean 223, 251, 269, 285, 287, 519CLOB 559, 575, 613date 264Datum 285DBURIType 655, 657HttpURIType 655, 710HttpUriType 472, 712httpUriType 481LOB 217, 285, 559, 575, 752long, raw, long raw 287, 559Medientypen 284NCLOB 559, 575nested table 810Numerische Datentypen 284Objektoriente Datentypen 337Oracle-definierte, komplexe Typen 283Oracle-Spatial 284Originäre Oracle-Datentypen 282PL/SQL-exklusive Datentypen 287Record 288, 794ref_cursor 751SQL-Datentypen 282Table 283, 337, 341URIType 284, 655varchar2 und char 286Varray 283, 337, 810XDBURIType 656, 666XMLType 284, 481, 606, 617, 642Zeichentypen 285

Datentyp von Tabellenspalten 138Datenverarbeitung 395Datenzugriff über das Web 748

Prozedur über HTTP aufrufen 749Webservices aus PL/SQL 750

Datenzugriff über PackagesIntegration von Geschäftsregeln 746

Kapselung von DML-Operationen 744Vermeidung von Triggern 745

Datenzugriff über verteilte Cursor 751Arbeit mit LOBs 752

Datumsfunktion 252DBMS_Profiler 50Ddefiners Right (DR) � Authid-KlauselDead Lock � DatenkonsitenzDebugger 51Denormalisierung 113DIANA 33DICOM 479, 481Directory 577, 847, 853Diskussion

Abgrenzung von Zeitintervallen 377Einsatz eines Schleifentyps 302Einsatz von Triggern 391Einsatz von Triggern für Defaultwerte 372Implizer oder expliziter Cursor 423Lösung des Mutating-Table-Problems 389Refaktorisierung des Meldung-Objekts 795Speicherung von Daten in objektrelationalen

Tabellen 613Speicherung von XML in der Datenbank 610Variablen und das Data Dictionary 289Wie und wo werden Fehler bearbeitet? 484Zugriff auf Daten über View oder VPD 765

DRCP � Database Resident Connection Pool (DRCP)

Dynamisches SQL 249, 324Bindevariablen 326DBMS_SQL 330Execute Immediate 325mit Cursorvariablen 328Sicherheit 333SQL-Injection 333, 334Vermeidung von SQL-Injection 336Zuweisung von Bindevariablen 328

E

Eigentümerrecht 768Ein- und Ausgabeparameter 257, 258, 519Enterprise Service Bus (ESB) 750entfernte Ressource 182Error Logging 216Erweiterung von SQL 24, 266, 513, 517

Anforderungen an PL/SQL 519deterministische Funktion 518

1452.book Seite 867 Donnerstag, 5. August 2010 3:55 15

Page 75: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

868

Index

Externe Funktion 517Funktion 519Funktion existiert nicht 517Gruppenfunktion erstellen 538Nebenwirkungsfreiheit (Purity) 520Optimizer Hint 520SQL-Fähigkeiten 514SQL-Lösung unverhältnismäßig 518

Exception 254, 255, 483exec 254

F

Factory 656Fassade 204Fehlerbehandlung 24, 483

Anwendungsfehler erstellen 495benannte Fehler 489Fehlerpackage 496Fehlertrigger 505nicht benannte Fehler benennen 494Oracle-Fehler 483raise_application_error 495SQLCode 491SQLErrm 491Utility lmsgen 498value_error 303

Fehlerbehandlungsteil � ExceptionFramework 151Fremdschlüssel 146FTP 651Funktion 115, 266, 513

analytische Funktion 225deterministisch 111Gruppenfunktion 223, 225Nebenwirkungsfreiheit 224Textfunktion 223Umwandlungsfunktion 223Zeilenfunktion 223

G

generische Datenbankprogrammierung 182, 193, 196, 198, 205

Geschäftslogik 135, 229, 746, 747gespeicherte Prozedur � ProzedurGruppenfunktion 513, 538

Arbeitsweise 539Initialisierung 539, 540

Iteration 539, 540Terminierung 539, 541Zusammenführung 539, 541

Gültigkeitsbereich von Variablen 255

H

Hash 163, 737Hintergrund

Objektorientierung 541Rechte von PL/SQL-Code 552

Historisierung von Daten 226HTML 603HTTP 612, 651, 726, 748, 749

I

I18N 777imp 124impd 124Impedance Mismatch 22, 183

Cache 188Datensuche 184Identität 183Koppelung von Logik und Daten 191Lazy Load 187Lesestrategie 186Objekthierarchie 188referenzielle Integrität 192Statement of Truth 184, 191Table per Class 189Table per Class Family 190Vererbung 188

implizite Konvertierung 290Index 95, 100, 101, 105, 142

Benutzung von Indizes 107Binärbaum-Index 107, 109Bitmap-Index 107funktionsbasierter Index 107, 108, 111,

149, 225, 521, 523Index-Range-Scan 109, 111Reverse-Key-Index 107, 110Unique-Index 112, 143

Initialisierung eigener Fehler 280Integration von Oracle in Applikationen 26,

725Integration von SQL in PL/SQL 249Invokers Right (IR) � Authid-Clausel

1452.book Seite 868 Donnerstag, 5. August 2010 3:55 15

Page 76: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

869

Index

J

Java 478Java Message Service (JMS) 859Java Naming and Directory Interface (JNDI)

864Java Server Faces 748JDBC 171, 726, 751, 864Job 244Journaled Filesystem 574

K

Kapselung 182Kollektion 249, 310, 407

spärlich besetzt 410Kompileranweisung 279Kompilieren 115Komponententest 52konditionale Kompilierung 295, 843, 846

Abfrage-Direktive 297Auswahl-Direktive 297Error-Direktive 299

Konstruktormethode 338Kontrollstruktur 249, 291

Case-Anweisung 292, 296Case-Anweisung (bedingt) 294Case-Anweisung (einfach) 293Einfache Schleife 300For-Schleife 301if - then - else-Anweisung 291konditionale Kompilierung 295Nicht empfohlene Anweisungen 307Schleifenoptionen 302While-Schleife 303

L

Language for ADA (DIANA) 465Latch 166, 170, 171Lazy Load 201LDAP 478, 759Lesekonsistenz 65, 128, 129, 149, 194, 202,

348, 354, 368, 735Leserecht 91LOB 118, 559, 752, 753, 778

API für BFILE 583BFile 118BLOB 118

CLOB 118Einsatz in der Datenbank 560LOB als Parameter 571LOB als PL/SQL-Variable 565Long-Datentyp 119mit Daten füllen 563NCLOB 118Null-LOB, leeres LOB 561persistentes LOB 565, 567Schreibzugriff 579Secure Files 572SQL-Semantik 567Technische Struktur 560Variablendeklaration und -initialisierung

566Verarbeitung mit dbms_lob 578

Lock 165, 170, 171Log4J 27log4plsql 777, 781, 782, 864Logging-Package 27lost update 727

M

Mächtigkeit von SQLFazit 221

Maschinenabhängiger Bytecode (M-Code) 465

Maskierung von Variablen 255Massenverarbeitung von Daten 409

Bulk-Select 414Fehlerkontrolle 413

materialisierte Datensicht � DatensichtM-Code � Pseudocode (P-Code)Mengenverarbeitung mit Cursorn 423Message Oriented Middleware (MOM) 859Model-View-Control (MVC) 748MoneyType 697

Implementierung 699Implementierung des Package coa_money

705Package-Körper coa_money 707Rechteverwaltung in Oracle 11g 718Typkörper 701Typspezifikation 699Vererbung 721Vorüberlegungen 697

Multi-Table-Insert 746Mutating-Table-Problem 520, 745

1452.book Seite 869 Donnerstag, 5. August 2010 3:55 15

Page 77: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

870

Index

N

Namenskonvention 257National Language Support (NLS) 122, 124

Längensemantik 125National Language Support (NLS) � Zei-

chensatzkodierung bei OracleNebenläufigkeit 379.NET Framework 748Normalisierung 113Nullwert 112

O

Obektrelationales Mapping (ORM) 200Cache 201Hibernate 201Kapselung der SQL-Dialekte 201Lazy Load 201Mapping von Objekten auf Tabellen 200Oracle Top Link 201Transaktion 201

Object Change Notification (OCN) 742Objekt-ID (OID) 183Objektorientierung 25, 27, 120, 181, 273,

395, 604, 681, 748, 778, 782abstrakte und finale Klasse 687Alles ist ein Objekt 684Auswirkung auf die Datenbankprogrammie-

rung 693Best Practices 723Einführung 683Einsatz von Objekten als Triggerersatz 392extern implementierte Methode 697Gruppenfunktion in PL/SQL 540Instanziierung 338Klassenstruktur 691Konstruktorfunktion 696Member-Methoden 696objektrelationale Tabelle 613statische Methode 688, 696Typ 480, 695Typkörper 695Typspezifikation 695Vererbung 686, 695Vergleich mit relationalem Weltbild 689

Objektprivileg 91, 167Objektrelationales Mapping (ORM) 182,

197, 200OLE-DB 117

Online Analytical Processing (OLAP) 60, 479

Online Transactional Processing (OLTP) 85, 87, 97

Online-Dokumentation 29, 2492-Day Administration Guide 37AskTom 33Concepts-Guide 31Data Warehousing Guide 34New Features Guide 32PL/SQL Language Reference 33PL/SQL Packages and Type Reference 34SQL*Plus Quick Reference 40SQL*Plus User’s Guide 40XML Developers Guide 34

Open Database Connectivity (ODBC) 117optionale Parameter 264Oracle Advanced Security 573Oracle Advisor 479Oracle by Example (OBE) 30Oracle Data Mining 479Oracle Express Edition 36Oracle Forms und Reports 237Oracle Heterogenous Services 117Oracle Managed Files (OMF) 573Oracle Packages 34Oracle Packages � PackageOracle Spatial 29Oracle Streams AQ 864Oracle-Datenbank 21, 88, 99

Anmeldung 68Archive Process 64Aufbau der Datenbank 21Backup & Recovery 66, 67, 84Checkpoint 63Connection 71Data Dictionary 65Database Block Writer 62Data-Block-Buffer-Cache 58Data-Dictionary 113, 115Data-Dictionary-Cache 60Datenbankblock 136Datenbankblocknummer 106Datenbankjob 114Datenbankobjektnummer 106Datendatei 55, 65, 67Datendateinummer 106Dedicated-Server-Verbindung 78, 85Default-Pool 58Dispatcher 79, 80

1452.book Seite 870 Donnerstag, 5. August 2010 3:55 15

Page 78: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

871

Index

DRCP 87Eazy Connect (EZConnect) 73, 79filesystem_like_logging 574Fixed SGA 59Foreign-Key-Constraint 21Full-Table-Scan 100Grundlagen 55High Watermark 100Hintergrundprozess 56, 60indexorganisierte Tabelle 791Init-Ora-Datei 67Installation 68Instanz 55, 69, 96Java-Objekt 115Java-Pool 57JDBC 75JDBC-Treiber 72Keep-Pool 58Kontrolldatei 55, 67, 69Large-Pool 57LDAP 72, 77Library-Cache 60, 162Listener 70, 79, 169listener.ora 73Log-Switch 63, 66, 67Log-Writer 62materialisierte Sicht 480Mount der Datenbank 69Net8-Protokoll 242nologging 574Null-Pool 58ODP.NET 75Öffnen der Datenbank 69Optimizer 108, 160Oracle Net Service 72Oracle-Connection-Manager 72Oracle-Homeverzeichnis 67Oracle-Net-Services 72Overflow-Segment 793Parameter 96Parameterdatei 67Passwortdatei 67, 68physical reads 44physikalische Dateien 65PL/SQL-Objekt 115PMON 156Process Global Area (PGA) 59, 79Process Monitor 61Queue 80, 86, 860Quota 93

Recovery Manager 57Recycle-Pool 59Redo-Log-Archiv 66Redo-Log-Buffer 59, 62, 66Redo-Log-Datei 55, 63, 66, 67RMAN 169Rollback-Segment 133Row-ID 100, 105, 106, 111, 730Savepoint 351Schema 87Secure Files 572, 614Serverprozess 79Session 71Shared Server 239Shared-Pool 57, 59Shared-Server-Parameter 81Shared-Server-Prozess 80, 81Shared-Server-Verbindung 79, 80SID 74Slave-Prozess 64Sonstige 115Speicher-Pool 57Speicherstruktur 109Sperre 368SPfile-Datei 67sqlnet.ora 73Start der Datenbank 69Streams-Pool 57System Global Area 55, 57, 67System Monitor 61System-Change-Number (SCN) 155, 737Systemtabelle 65Tablespace 87TCP/IP 74temporärer Tablespace 565TNS 73, 78tnsnames.ora 73, 78, 80, 83, 242Transportabler Tablespace 480Treiber 72User Global Area (UGA) 79Verbindungaufbau 70Verbindungsaufbau 84Verteilte Verbindung 85Webserver 72, 654XDB 76XMLType 120

Oracle-Magazine 30Oracle-Spatial 479Organisation von PL/SQL-Code 256ORM � Obektrelationales Mapping (ORM)

1452.book Seite 871 Donnerstag, 5. August 2010 3:55 15

Page 79: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

872

Index

P

Package 23, 115, 229, 250, 272, 441, 745Abhängigkeitskette 458apex_* 476Aufruf von Prozeduren und Funktionen 276ctx_* 479Datenbank-Utilitys 475dbms_* 252dbms_addm 479dbms_advisor 479dbms_application_info 477, 789dbms_aq 862dbms_aq_* 478dbms_aqadm 860dbms_assert 336, 477dbms_backup_restore 480dbms_cdc_publish 478dbms_cdc_subscribe 478dbms_comparison 479dbms_connection_pool 478dbms_crypto 475, 521, 698, 762, 766, 768dbms_data_ming_* 479dbms_ddl 467, 469dbms_debug 51, 477dbms_describe 477dbms_epg 477dbms_errlog 217, 477dbms_fga 245dbms_java 478dbms_job 478dbms_ldap 478, 480dbms_lob 562, 566, 575, 577, 578, 590,

629, 843dbms_meta_data 479dbms_metadata 243dbms_mgd_id_util 479dbms_monitor 477, 480dbms_mview 34, 480dbms_network_acl 719dbms_network_acl_utility 480dbms_obfuscation_toolkit 475, 698dbms_odci 477dbms_olap 479dbms_output 34, 252, 276, 475, 597, 783,

855dbms_pipe 478dbms_profiler 50, 477dbms_random 303, 475, 520

dbms_rcvcat 480dbms_rcvman 480dbms_scheduler 478dbms_server_alert 479dbms_shared_pool 479dbms_space_* 479dbms_spm 480dbms_sql 330, 468, 480dbms_sqldiag 480dbms_sqlpa 479dbms_sqlune 480dbms_stats 480dbms_streams_* 478dbms_system 855dbms_trace 477dbms_tts 480dbms_utility 344, 420, 475, 491dbms_version 291, 475dbms_xdb 253, 660dbms_xdb_version 677dbms_xmldom 641, 643dbms_xmlgen 621, 625, 631, 647dbms_xmlindex 650dbms_xmlparser 641, 643dbms_xmlquery 647dbms_xmlsave 615, 647dbms_xmlschema 650, 665dbms_xmlstore 615, 647dbms_xmltranslations 650dbms_xplan 480dbms_xslprocessor 641htf 477htp 477, 597Implementierungsteil 274Initialisierungsprozedur 275, 444, 445Konstante 458Körper 272, 274Oracle-Packages 470owa_* 476owa_cookie 476owa_opt_lock 476Packagekörper 443Packagespezifikation 272, 442, 447sdo_* 479sem_apis 477sem_perf 477standard 286, 473, 489Trennung von öffentlicher und privater Logik

442

1452.book Seite 872 Donnerstag, 5. August 2010 3:55 15

Page 80: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

873

Index

Überladung 452util_dbms 816utl_* 475utl_compress 475utl_dbws 475utl_encode 475utl_file 475, 847, 852utl_http 476, 749utl_i18n 476utl_inaddr 476utl_lms 476, 494, 503, 810utl_mail 295, 476, 698, 857utl_pipe 859utl_smtp 295, 476, 698utl_url 476, 477utl_utcp 476Verschlüsselung von Code 464Verwendung 441Vorteile 272Vorwärtsdeklaration 276wpg_docload 472Wrap-Utility 465

Parameter 256nls_language 836session_max_open_files 584

Parameterzuweisung 263explizit 263positionell 263

Passwort 168P-Code � Maschinenabhängiger Bytecode

(M-Code)Performanz 104, 107, 136, 181, 182, 196,

202, 204, 272, 427, 431, 765, 848Datenbank-Constraints 143Einfluss der Programmierung 169Implementierung eines Tests 171Latching 128Locking 128Mengenverarbeitung 177Sperren 170Umgebungswechsel 176

Pivotierung 516PL/SQL 17, 21, 23, 29

Blockstruktur 23Syntax 23Tuning 33

PL/SQL im Einsatz 24PL/SQL Server Pages 749

PL/SQL-Befehl%RowType 289%Type 289authid current_user 278Authid-Klausel 277begin 251, 252bult_exceptions 413case 291, 292continue 309declare 251, 252, 269default 264deterministic 520end 251exception 251, 842execute immediate 325exit 301finally (nicht existent!) 427for - cursor - loop 323forall 410For-Loop 301for-reverse-loop 303function 267goto 309if - then - else 291in 258in out 258in out nocopy 258label 307Loop 300nocopy 258nocopy-Klausel 571out 258package 273parallel enable 521pipe row 417pipelined 416plsql_warnings 572pragam autonomous_transaction 280Pragma-Klausel 279Pseudospalte row 399Pseudovariablen new/old 270raise_application_error 370, 495, 498ref_cursor 751return 267sqlcode 491, 501sqlerrm 252, 491when others 484where-current-of-Klausel 730While-Loop 303Zuweisungsoperator 251, 264

1452.book Seite 873 Donnerstag, 5. August 2010 3:55 15

Page 81: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

874

Index

PL/SQL-Befehl � KompileranweisungPL/SQL-Block 250

Ausführungsteil 250Deklarationsteil 250Ende 250, 256Fehlerbehandlungsteil 250

PL/SQL-Developer 41, 50PL/SQL-Grundlagen 33PL/SQL-Profiler 789PL/SQL-Referenz 29Pragma

autonomous_transaction 346, 857exception_init 535, 846restrict_references 521

PraxisbeispielAbleitung einer Variablen aus dem Data Dic-

tionary 289Ableitung eines Record aus dem Data Dictio-

nary 312ACL für E-Mail-Versand administrieren 858Administration der XDB 654Administrationsaufgabe 253Advanced-Queueing-Tabelle anlegen 860Aktualisierung von Daten mit Records 399,

400Analyse der XML-Datenbank 652Analytische Funktion 211anonymer Block 251API für dbms_crypto 767API zum Laden von LOBs aus der Datenbank

584API zum Lesen von LOBs aus der Datenbank

592Arbeit mit hierarchischen Objekten 801Assertionsmethoden 486Auditierung 376Aufruf einer Prozedur mit Ausgabeparame-

ter 261Ausgabe eines LOB über http 597autonome Transaktion 280bedingte Case-Anweisung 294bedingter Primärschlüssel 793Benennung eines Fehlers 489Benenung eines Fehlers 494Berechnung der Fakultät 528Bindevariable für Wertelisten 419Bindevariablen 163Check-Constraint 146CLOB in Datei schreiben 844

Code-Generator für Gruppenfunktionen 549Compound-Trigger 355Cursorausdruck 436Cursor-For-Schleife 323Cursorvariable 433Cursorvariable als Parameter 434Datenbank-Link 117Datenbanktrigger 270Datenbanktrigger after logon 359Datensicherheit durch Trigger 233Datensicht mit Check-Option 358dbms_metadata 243Definition einer Assoziativen Tabelle 315Definition eines parametrierten Cursor 322Deklaration einer assoziativen Tabelle 407Deklaration einer Nested Table 341Deklaration eines Cursors 318Deklaration eines expliziten Records 401Deklaration eines Packages 273Deklaration eines Records in einem Package

402Deklaration eines VArray 338Deklaration von Datentypen im Package

standard 286Ein LOB mit Daten füllen 563Ein Objekt als Ersatz für einen Record 406einfache Case-Anweisung 293einfache Funktion 266einfache If-Anweisung 292einfache Prozedur 256einfache Record-Definition 311einfache While-Schleife 303einfacher Package-Körper 274Einfluss der Programmierung auf die Perfor-

manz 169Einfügen von Daten mit Records 398Error Logging 216Erstellung einer ACL 719Erstellung einer Gruppenfunktion 542Erstellung einer sicheren Anwendung 762Erzeugun von XML aus einem Objekt 625Erzeugung einer ACL 673Erzeugung einer schemabasierten Tabelle

667Erzeugung von XML aus hierarchischen

Abfragen 630Erzeugung von XML mittels dbms_xmlgen

622Execute Immediate mit Bindevariable 326

1452.book Seite 874 Donnerstag, 5. August 2010 3:55 15

Page 82: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

875

Index

Execute Immediate mit Cursorvariable 329Execute-Immediate 325explizite Parameterübergabe 263Fakultätsfunktion 300, 301Fehler initialisieren 280Fehlerbehandlung über einen Fehlertrigger

505Fehlerdeklaration mit lmsgen 499Fehlerpackage 496Fehlerstack 492Fine Grained Auditing (FGA) 245For-Schleife 306Funktion mit Ausgabeparameter 267Funktionsbasierter Index 111geschachtelter Block 254geschachtelter Record 312Hierarchische Abfrage 214Hilfsfunktion für die Arbeit mit LOB 584If-Anweisung 292Implementierung des Default-Meldungsmo-

duls 804Implementierung des Meldung-Objekts 795Implementierung des Message-Grundmo-

duls 803Implementierung eines Packages 444Impliziter versus expliziter Cursor 424Index Range Scan 109Instanziierung eines Objektes nach Namen

817Instanziierung eines Objekts 339Instead-Of-Trigger 357, 381Iteration über eine assoziative Tabelle mit

Textschlüssel 817Jurassic-Park-Phänomen 144konditionale Kompilierung 296, 297, 299,

845Konstanten-Package 459Lesen einer Ressource aus dem Internet 713loadpsp 241LOB 629LOB, Null-LOB. leeres LOB 561LOB-Variable deklarieren 566Lösung des Mutating-Table-Problems 384Maskierung von Variablen 255Massenverarbeitung mit assoziativer Tabelle

409Massenverarbeitung mit Bulk-Kontrolle 412Massenverarbeitung mit Bulk-Select 415

Massenverarbeitung von Daten mit Fehler-kontrolle 413

Materialisierte Sicht 114Meldungstabelle 792Merge-Anweisung 835MoneyType 697Mutating-Table-Problem 353Objekthierarchie erstellen 722optimistisches Sperren 733optimitisches Sperren mit SCN 738ORA_ROWSCN 154Parametertabelle 463, 550, 790Parametertabelle über View und Synonym

785pessimistisches Sperren 727PL/SQL Server Pages 240PL/SQL Web Toolkit 239PL/SQL-Package dynamisch erzeugen 844Probleme mit impliziter Konvertierung 290Prozedur mit Aufruferrechten 278Prozedur mit Ausgabeparameter 260Prozedur mit eingebetteter Prozedur 262Prozedur mit optionalem Parameter 264Prozedur mit Parameterm 259Prozedur mit problematischen Parametern

265Prozedur zur Datenänderung 229Prüfung auf vorhandene Daten 425Public-Synonym erzeugen 855Record mit SQL-Returning-Klausel 404Refaktorisierung der Fakultätsfunktion 484Registrierung eines XML-Schemas in der XDB

663Relationale Daten aus XML mittels SQL/XML

extrahieren 636Scheduler und Job 244Schemata 90Schlechte Schleife 305Schleife mit Label 307Schreibzugriff auf ein LOB 579Secure Files 573Selektiver Primärschlüssel 146Sequenz 116Spezifiaktion eines Packages 442SQL zur Lösung prozeduraler Probleme 515SQL/XML 609, 617SQL/XML-Anweisung 839SQL/XML-Geschwindigkeitstest 619SQL-Anweisung call 254

1452.book Seite 875 Donnerstag, 5. August 2010 3:55 15

Page 83: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

876

Index

SQL-Anweisung zum Pivotieren von Spalten 819

SQL-Injection 333, 335Synonym 117Tabellenfunktion als virtuelle Tabelle 420temporäres versus persistentes LOB 567Top-N-Analyse 429Trigger 226, 235Trigger before drop 390Trigger on servererror 391Trigger zur Datenkonsistenzprüfung 369Trigger zur Erzeugung von Defaultwerten

371Trigger zur Historisierung von Daten 378Trigger, um Reihenfolge von Werten zu

garantieren 372Übergabe beliebig vieler Parameter an eine

Methode 810Überladung von Methoden 453Umwandlungsfunktion 224Verschlüsselung von Code mit dbms_ddl 468Verschlüsselung von Code mit Wrap-Utility

465Verwendung der empty_clob()-Anweisung

564Verwendung der nocopy-Klausel 572Verwendung der Pseudovariablen 271Verwendung der URI-Factory 657Verwendung der XMLTable()-Anweisung

633Verwendung des DBURIType 657Verwendung des Package dbms_xdb 660Verwendung des Packages dbms_crypto 763Verwendung des Sessionkontextes 764Verwendung einer Assoziativen Tabelle 315Verwendung einer Nested Table 341Verwendung einer Tabellenfunktion 416Verwendung eines BFILE 577Verwendung eines Cursors 320Verwendung eines objektorientierten Typen

in SQL 693Verwendung eines Record 313Verwendung eines Varray 339Verwendung von Aufruferrechten 768Verwendung von BFILE 583Verwendung von dbms_sql 331Verwendung von dbms_xdb_version 677Verwendung von LOB 569Verwendung von nicht-SQL-Datentypen als

Eingabeparameter 529

Verwendung von Optimizer Hints 522Verwendung von SQL/XML 615Verwendung von XMLType 606Wrapper für utl_lms 501XML-Aktualisierung mit dbms_xmlstore

648XML-Programmierung mit dbms_xmldom

642XMLType-funktionsbasierter Index 610XQuery-Abfrage 635XSQL Publishing Framework 242Zugriff auf Daten mit WebDAV 651

PraxisberichtAbfragegenerator 198Datenkonsistenz 232effizientes SQL 194, 195generische Datenbankprogrammierung 198Grenzen von XML-Verarbeitung 605Konsistene Verwendung von Datentypen

140Modellierung von XML in der Datenbank

610objektrelationales Mapping 197Spaltentyp 138Tablespace 94Transaktion 194Unnötige Programmierung 470

Primärschlüssel 101, 108, 141Programmiermodell 151Programmierung 223

Administrationsunterstützung 242Anwendungsprogrammierung 236Application Express (APEX) 237Auditing 245Client-seitiges PL/SQL 237clientseitiges PL/SQL 236Datenkonsistenz 225Datenkonsistenz mittels PL/SQL 232Datensicherheit 233Datensicherung 245Datenzugriff über PL/SQL 229Embedded PL/SQL Gateway 238erweiterte Datenbankfunktionalität 223mod_plsql 238PL/SQL Gateway 238PL/SQL Server Pages 238, 240PL/SQL Web Toolkit 238, 239PL/SQL-Skript 243Webanwendungen in PL/SQL 236

1452.book Seite 876 Donnerstag, 5. August 2010 3:55 15

Page 84: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

877

Index

Webanwendungen mit PL/SQL 238XSQL Publishing Framework 238, 241

Programmierung der Datenbank 22Programmierung von Triggern 23Prozedur 115, 204, 256, 747, 753

Parameter 257Spezifikation 231

Pseudocode (P-Code) 465Pseudospalte

column_value 419, 421level 631ora_rowscn 737user 520

Q

Query Result Change Notification (QRCN) 742

R

Radio Frequency Identification (RFID) 479Record 310, 395, 462

Ableitung aus dem Data Dictionary 312Definition durch das Data Dictionary 395expliziter Record# 401Insert- und Update-Anweisung 398Objekt als Alternative 406Returning-Klausel 404

Recovery Manager (RMAN) 84, 480Recovery Manager (RMAN) � Oracle-Daten-

bankRedundanz 167referentielle Integrität 137Rekursion 537Relationales Datenbankmanagementsystem

(RDBMS) 167, 181, 193, 196, 198Remote Procedure Call (RPC) 604RFID 481Rollenkonzept 167Round-Half-Even-Verfahren 714Rules and Expressions 481RunStats 45, 170

S

Schachtelung von Blöcken zur Fehlerbe-handlung 254

Scheduler 243, 244

Schema 88, 91, 92, 97, 168, 277Schleifenkonstruktion 254Schreibkonsistenz 128, 132Schreibrecht 91, 229Secure Application Role (SAR) 760, 762,

765Secure Files 119, 752Semaphore 166Sequenz 116Sequenz � AutowertSerialisierung 166Service Oriented Architecture (SOA) 604,

748, 750Session 157, 161, 732, 848Sessionkontext 206

USERENV 206, 233, 234Sessionvariable 103Sicherheitsdomäne 168, 205Skalierbarkeit 196, 202, 205Smell 796SOAP 749Sperren von Daten 726

Database Change Notfication (DCN) 727, 741

optimistisches Sperren 727, 733, 736pessimistisches Sperren 727

SQL 17, 29ANSI-Standard 127hierarchische Abfrage 212Isolation-Level 129, 130, 131ISO-Standard 127

SQL Developer 249, 251, 252SQL*Loader 353

Direct-Path-Load 353SQL*Plus 38, 41, 150, 249, 251, 252, 338,

775set serveroutput on 252Zeichen / 253

SQL/XML 604, 610, 615, 617, 618, 629, 631, 638, 661, 675, 711

SQL-Anweisung 79, 80, 113, 158after update 270alter session 334analytische Funktion 209analytische Funktionen 514ANSI-Standard 127Atomizität 216Ausführen (lesend) 160Ausführen (schreibend) 162

1452.book Seite 877 Donnerstag, 5. August 2010 3:55 15

Page 85: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

878

Index

avg 193bfilename() 578Case 112case 292, 515cast 625column_value 607columns-Klausel 712commit 346create Index 107create or replace 257create Sequence 116create session 698, 759cursor 422, 435DDL-Anweisung 520debug any procedure 51debug connect session 51decode 291, 516delete 100, 104, 345distinct 576DML-Anweisung 112, 133, 225, 345drop 757empty_clob() 564, 578equals_path 675Error-Logging 209explain plan 41extract 370for each row 347for update-Klausel 729full join 787group by 576hierarcische Abfrage 209identified-using-Klausel 762insert 102, 116, 345intersect 576ISO-Standard 127, 198Log-Error-Klausel 514, 746map-Klausel 697merge 133, 345, 746, 835minus 576multiset 625new 721not-final-Klausel 803not-instantiable-Klausel 803nowait-Klausel 729Optimierung 159, 160, 162order by 576order-Klausel 697Parsen 159Pivot-Klausel 516

Projektion 186reguläre Ausdrücke 376replace 257, 567returning-Klausel 404rollback 346rowdependencies-Klausel 738scn_to_timestamp 739Select for update 156Set Transaction 133substr 567sys_context 764sys_refcursor 435sysdate 520systimestamp 370table() 607, 637truncate 101, 757under-Klausel 722union / union all 576update 153, 230, 345updateXML 638, 675, 839URIFactory 656with-grant-option-Klausel 764xmlagg 618, 633xmlattributes 616xmlelement 616XML-Erzeugung mit SQL 515xmlforest 616xmlsequence 637xmlTable 634, 711XMLTable() 632, 633

SQL-Developer 40SQL-Skriptdatei 124, 243

utlxplan.sql 41Stored Procedure � ProzedurSynonym 117Syntax 249, 250Systemprivileg 88, 167

T

Tabelle 90, 99exklusiv sperren 369Full Table Lock 152Full Table Scan 108, 139, 152Global Temporary Table 99, 102Hash-Partition 104Heap Organized Table 99Heap-Organized-Table 99, 109Index Organized Table 99, 101

1452.book Seite 878 Donnerstag, 5. August 2010 3:55 15

Page 86: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

879

Index

List-Partition 104Partitionierte Tabelle 103Pseudospalte 105Pseudospalte ORA_ROWSCN 154Range-Partition 103

Tabellenfunktion 344, 415Tablespace 88, 89, 93, 94, 168

Quota 168Read Only Tablespace 94Temporary Tablespace 94

TCP/IP 72temporäres LOB 567Tiefenkopie 571TKProf 46tnsnames.ora 117tnsping 74Toad 41Token 761TopLink 733Transaktion 22, 61, 62, 65, 127, 132, 165,

182, 194, 202, 231, 346, 520, 726, 729autonome Transaktion 279Transaktionslog 133, 136Transaktionsschutz 128Unit of Work (UoW) 136, 201, 732Verteilte Transaktion 118

Trigger 115, 147, 225, 245, 269, 279, 345, 520Anforderungen 271Anweisungstrigger 347Anwendungstrigger 237Auditierung durch Trigger 375Auslösereihenfolge 352Auslösung 351benutzerbezogene Ereignisse 364Compound-Trigger 355Compound-Trigger und Mutating-Table 384Datenbankereignis 245, 345, 362Datenbanktrigger 359Datenintegrität 367DDL-Ereignis 389Defaultwerte setzen 371Definition 269DML-Ereignis 369DML-Trigger 345Einsatzbereiche 367Ereignisattribute 360Erweiterung der Datenkonsistenzprüfung

369

follows-Klausel 352Historisierung von Daten 377Instead-Of-Trigger 357, 381kaskadierende 353konditionale Ausführung 349Körper 350Mutating-Table-Problem 353, 368, 379,

395Pseudovariablen new/old 350Spezifikation 349Systemereignis 225, 391Update-Reihenfolge festlegen 372when-Klausel 349Zeilentrigger 347zirkuläre Triggerdefinition 354

U

Überladen von Prozeduren und Funktio-nen 272

Überladung 452Überladung � PackageUmgebungswechsel 224, 517Unicode 575Unit of Work (UoW) � Transaktionunverzerrtes (mathematisches) Rundungs-

verfahren 701URL 577, 710

V

Variable 251View � DatensichtVirtual Private Database (VPD) 765

W

WebDAV 72, 76, 416, 651, 654, 671WebService 182, 225, 604, 750, 753, 781Weiterführende Literatur 34Workshop 26Workshop Logging-Package 777

Architektur und Überblick 778Ausgabemodul Alert-Datei 855Ausgabemodul E-Mail 857Ausgabemodul JMS 859Ausgabemodul Tabelle 856Ausgabemodul Trace-Datei 847Ausgabemodul-Objekt 782

1452.book Seite 879 Donnerstag, 5. August 2010 3:55 15

Page 87: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

880

Index

Implementierung 790Implementierung der Log-Admin-Package-

Spezifikation 830Implementierung der Logging-Package-Spezi-

fikation 811Implementierung des Kontextes 808Implementierung des Log-Admin-Package-

Körpers 832Implementierung des Log-Admin-Packages

828Implementierung des Logging-Package-Kör-

pers 814Implementierung des Logging-Packages 811Implementierung des Meldungsgrundmoduls

800Implementierung einer Parameterliste 809Implementierung Meldungstabelle 791Implementierung Parametertabelle 790Kontext 781Meldung-Objekt 780Meldungsobjekt 794Meldungspackage 789Tabellen 784Test des Logging-Packages 827Weitere Ausgabemodule 846

Workshop Sichere Anwendung 757Archtitektur 758Aufsetzen der Schemata 762Logon-Prozedur 761Packages 766Projektbeschreibung 757Test 772Token 770

X

XLIFF 829, 838, 840XML 25, 27, 120, 125, 241, 242, 603, 750,

752, 778, 829BinaryXML 613DOM-Baum 605, 615, 629, 637, 638Erzeugung aus Objekten 624Erzeugung durch dbms_xmlgen 622Erzeugung von XML aus hierarchischen

Abfragen 629For-Let-Order By-Where-Return (FLOWR)

632getnumberval()-Anweisung 609Namensraum 639

Null-Namespace 668Oracle-Parser 640Packages zur Erzeugung und Speicherung von

XML 647Paginierung von XML-Abfragen 631PL/SQL-Packages für XML 640Programmierung mit SAX 638Relationale Daten aus XML extrahieren 631SAX 615Simple API for XML (SAX) 639Sonstige PL/SQL-Packages 650Speicherung ind der Datenbank 613sys$nc_rowinfo 607Verarbeitung mit PL/SQL 638Weißraum 639wohlgeformt 613XML aus relationalen Daten erzeugen 615XML Schema Definition Language (XSD)

603XPath 605, 609, 632XQuery 632XSD 613, 650, 662, 667XSL-FO 604, 640XSL-T 604XSLT 628, 632, 638

XML Database (XDB) 72, 76, 239, 416, 478, 605, 641, 651ACL 671Arbeit mit ACLs 673Dokumente per Drag & Drop einfügen 659Dokumente per PL/SQL einfügen 660Dokumente verwalten 659Einführung 652Registrierung eines Schemas 663schemabsierte Tabelle 666Speicherung mit XML-Schema 662Versionierung von Ressourcen 676Verwaltung von Dokumenten 654Zugriffsschutz und Sicherheit 670

XML Localization Interchange File Format (XLIFF) 650

XML SQL Utility (XSU) 647XML-Fragment 618XMLType 25

Analysemethoden 612appendChild()-Anweisung 612Bearbeitungsmethoden 612createxml()-Anweisung 612deleteXml()-Anweisung 612

1452.book Seite 880 Donnerstag, 5. August 2010 3:55 15

Page 88: Store & Retrieve Data Anywhere - Oracle PL/SQL...In einem ersten Rundblick betrachten wir die Oracle-Datenbank aus Sicht eines Entwicklers. Hier lernen Sie die wichtigsten Strukturen

881

Index

existsNode()-Anweisung 612extract()-Anweisung 612, 631, 634, 637extract-Anweisung 609extractValue()-Anweisung 612, 631insertXmlBefore()-Anweisung 612isFragment()-Anweisung 612isSchemaValid()-Anweisung 612isSchemaValidated()-Anweisung 612Konstruktorfunktion 611Methoden 611text()-Anweisung 637transform()-Anweisung 612Verwendung von XMLType als Spaltentyp

606XSD 25XSLT 25, 241

Z

Zeichensatzkodierung 37, 120ASCII 121ISO-8859 121Multi-Byte-Zeichensatz 120Single-Byte-Zeichensatz 120Unicode 122UTF 122UTF-8 613

Zeichensatzkodierung bei Oracle 122Nationale Zeichensatzkodierung 124NLS 124

Zeitstempel 154Zugriff auf Daten über PL/SQL-Packages

743

1452.book Seite 881 Donnerstag, 5. August 2010 3:55 15