+ All Categories
Home > Documents > Java in Datenbanksystemen

Java in Datenbanksystemen

Date post: 08-Dec-2016
Category:
Upload: duongngoc
View: 215 times
Download: 3 times
Share this document with a friend
423
Java in Datenbanksystemen
Transcript
Page 1: Java in Datenbanksystemen

���������������� ����

Page 2: Java in Datenbanksystemen

�����������������

Page 3: Java in Datenbanksystemen

�����������������������������

���������������� ������������������������� �������������

An imprint of Pearson Education

München • Boston • San Francisco • Harlow, EnglandDon Mills, Ontario • Sydney • Mexico CityMadrid • Amsterdam

Page 4: Java in Datenbanksystemen

Die Deutsche Bibliothek – CIP-Einheitsaufnahme

Ein Titeldatensatz für diese Publikation ist bei Der Deutschen Bibliothek erhältlich.

Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt.Bei der Zusammenstellung von Abbildungen und Texten wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar.

Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig.

Fast alle Hardware- und Softwarebezeichnungen, die in diesem Buch erwähnt werden, sind gleichzeitig eingetragene Warenzeichen oder sollten als solche betrachtet werden.

Umwelthinweis:Dieses Produkt wurde auf chlorfrei gebleichtem Papier gedruckt. Die Einschrumpffolie – zum Schutz vor Verschmutzung – ist aus umweltverträglichem und recyclingfähigem PE-Material.

5 4 3 2 1

05 04 03 02

ISBN 3-8273-1889-0

© 2002 by Addison-Wesley Verlag,ein Imprint der Pearson Education Deutschland GmbH,Martin-Kollar-Straße 10–12, D-81829 München/GermanyAlle Rechte vorbehaltenEinbandgestaltung: Christine Rechl, MünchenTitelbild: Papaver orientale, Orientalischer Mohn. © Karl Blossfeldt Archiv – Ann und Jürgen Wilde, Zülpich/VG Bild-Kunst Bonn, 2001Lektorat: Martin Asbach, [email protected]: Sibille Mozer-Petkovic, MünchenHerstellung: Monika Weiher, [email protected]: reemers publishing services gmbh, Krefeld, www.reemers.deDruck und Verarbeitung: Kösel, Kempten, www.Koeselbuch.dePrinted in Germany

Page 5: Java in Datenbanksystemen

������

�������� ���

���� ����������� ��

� ��������������������������������� ���

1.1 Datenbanken – allgemein 171.1.1 Logische und physikalische Datenunabhängigkeit 181.1.2 Prozedurale und nichtprozedurale Schnittstellen 181.1.3 Effiziente Abarbeitung der Datenbankoperationen 181.1.4 Datenintegrität 191.1.5 Konkurrierender Datenzugriff 191.1.6 Datensicherheit 201.1.7 Datenschutz 201.2 Relationale Datenbanken 201.3 Datenbankdesign 231.3.1 Allgemeine Hinweise zur Normalisierung 241.3.2 Erste Normalform 251.3.3 Zweite Normalform 251.3.4 Dritte Normalform 261.3.5 Das Entity/Relationship-Modell 261.4 Die Datenbanksprache SQL 291.4.1 SQL-Anweisungen für Datendefinition 291.4.2 SQL-Anweisungen für Datenmodifikation 311.4.3 Sichten (Views) 341.4.4 Der Systemkatalog und das Informationsschema 351.4.5 Gespeicherte Prozeduren 371.5 Datenbankanwendungen programmieren 391.6 Zusammenfassung 39

� ����������������������������������� !"#$�%�� �&�

2.1 Objektorientierte Erweiterungen bei Oracle 412.1.1 Der Objekttyp 422.1.2 Kollektionen 452.1.3 Der Datentyp REF 50

Page 6: Java in Datenbanksystemen

� ������

2.2 Objektorientierte Erweiterungen bei Informix 532.2.1 Benutzerdefinierte Datentypen 542.2.2 Der Reihentyp 562.2.3 Kollektionen 602.2.4 Typ- und Tabellenhierarchien 662.3 Objektorientierte Erweiterungen bei DB2 692.4 Zusammenfassung 71

' ��"(��)��*�+���������������� ��'

3.1 Einleitung 733.2 Variablen, Konstanten und Datentypen 743.2.1 Vektoren (Arrays) und Strings 763.3 Schleifenanweisungen 773.4 Übersetzung und Ausführung eines Java-Programms 793.4.1 Java-Pakete 793.4.2 Java-Dateien 803.4.3 Java-Umgebung und -Umgebungsvariablen 813.5 Objektorientierte Sprachelemente bei Java 823.5.1 Erstellung neuer Typen 833.5.2 Sichtbarkeit 863.5.3 Konstruktore 873.6 Klassenhierarchien in Java 893.6.1 Die Klasse Object 913.6.2 Abstrakte Klassen und Methoden 923.6.3 Schnittstellen (Interfaces) 933.6.4 Polymorphismus in Java 953.7 Weitere Eigenschaften der Java-Sprache 973.7.1 Ausnahmen 973.7.2 Ein- und Ausgabe von Daten 1003.8 Zusammenfassung 103

����� �*� ,� �-�

& .�$�$��*� ,/� ��-�

4.1 Einleitung 1074.1.1 JDK und JDBC-API 1084.1.2 Das JDBC-Treiberkonzept 1094.2 Der Aufbau eines JDBC-Programms 1124.2.1 Treiber laden 1134.2.2 Die Herstellung der Verbindung zu einer Datenbank 1174.2.3 Erstellung der SQL-Anweisungen und ihr Senden an einen

Datenbank-Server 1194.2.4 Reihenweise Verarbeitung 1224.2.5 ResultSet-Erweiterungen 1234.2.6 Die Ausgabe der Ergebnisse 1274.2.7 Schließen der Verbindung zum Datenbank-Server 1284.3 Das Schlüsselwort ESCAPE 1294.4 JDBC und die Fehlerbehandlung 130

Page 7: Java in Datenbanksystemen

������ �

4.4.1 Die Klasse SQLException 1304.4.2 Die Klasse SQLWarning 1314.5 Übersetzung und Ausführung eines JDBC-Programms 1324.6 Zur Übersetzungszeit formulierte SQL-Anweisungen 1334.6.1 Die Verwendung der Methoden der ResultSet-Schnittstelle 1414.6.2 JDBC und Metadaten 1434.6.3 Scroll-Cursor 1484.6.4 Positionierte Änderung (Positioned update) 1504.7 JDBC und vorbereitete SQL-Anweisungen 1544.8 Die Klasse CallableStatement und gespeicherte Prozeduren 1594.9 Applet-Programmierung 1624.10 Große Objekte und JDBC 1674.11 JDBC und Transaktionen 1734.11.1 Einleitung 1734.11.2 Die JDBC-Methoden commit() und rollback() 1744.11.3 Isolierungsstufen 1774.12 Typumwandlung zwischen SQL und Java 1784.13 Zusammenfassung 179

� *� ,���0����������������������� ��1�

5.1 JDBC und objektorientierte Erweiterungen bei Oracle 1815.1.1 Der Objekttyp und der Datentyp REF 1815.1.2 VARRAY-Datentyp bei Oracle 1885.1.3 Geschachtelte Tabellen 1935.2 JDBC und objektorientierte Erweiterungen bei INFORMIX 1985.2.1 Der Reihentyp und Kollektionen bei Informix 1985.2.2 Informix-Typhierarchien 2055.3 JDBC und objektorientierte Erweiterungen bei DB2 2125.4 Zusammenfassung 212

2 3����%��)!4$(�����*� ,� ����

6.1 Performance – eine Einleitung 2156.1.1 Die Effizienz des Benutzer-Codes 2156.1.2 Das Datenbankmanagementsystem 2166.2 Die Durchführung von Performance-Tests 2166.3 Die Optimierung der Datenbankzugriffe 2176.4 Bearbeitung von vorbereiteten und nichtvorbereiteten

SQL-Anweisungen 2216.5 Scroll- und Nicht-Scroll-Cursor 2246.6 Ausführung der SQL-Anweisungen mittels batch 2296.7 Explizite und implizite Transaktionen 2326.8 Statement-Objekte 2366.9 Untersuchte Fälle ohne Performance-Unterschiede 2396.9.1 Die Methode setFetchDirection() 2396.9.2 Die Methode setFetchSize() 2406.10 Zusammenfassung 241

Page 8: Java in Datenbanksystemen

������

������ �"56*� �&'

� .�$�$��"56*/� ��&�

7.1 Einbettung der SQL-Sprache – eine Einführung 2457.1.1 Kennzeichnung der SQL-Anweisungen 2467.1.2 Host-Variablen 2467.1.3 Eingebettete SQL-Anweisungen und der Cursor 2477.1.4 Die dynamische SQL-Sprache 2487.2 SQLJ – die Grundlagen 2487.2.1 Vorteile von SQLJ im Vergleich zu JDBC 2517.2.2 SQLJ-Anweisungen 2527.2.3 SQLJ-Host-Ausdrücke 2537.2.4 Fehlerbehandlung bei SQLJ 2557.2.5 Übersetzung und Ausführung eines SQLJ-Programms 2557.2.6 Eingebettete SQL-Anweisungen ohne Ergebnismenge 2577.2.7 Die Einbettung einer SELECT-Anweisung ohne Iterator 2597.2.8 Die Einbettung der SELECT-Anweisung mit Iterator 2627.2.9 Verwendung eines Iterators mit der UPDATE- bzw. DELETE-Anweisung 2707.2.10 Gespeicherte Prozeduren und SQLJ 2737.2.11 Große Objekte in SQLJ 2777.3 Zusammenfassung 288

1 "56*���0����������������������� ��17

8.1 SQLJ und objektorientierte Erweiterungen bei Oracle 2898.1.1 Oracle-REF-Zugriff und Objekttyp-Änderung 2898.1.2 VARRAY-Datentyp bei Oracle 2968.1.3 Geschachtelte Tabelle mit Oracle 3008.2 SQLJ und objektorientierte Erweiterungen bei Informix 3048.2.1 Der Reihentyp und Kollektionen bei Informix 3058.2.2 Informix-Typhierarchien 3118.3 Zusammenfassung 315

7 3����%��)!4$(�����"56*� �'��

9.1 Die Optimierung der Datenbankzugriffe 3179.2 Blockweise Bearbeitung von SQL-Anweisungen bei Oracle 3209.3 Verwendung des Datentyps REF bei Oracle 3249.4 Ausführen von SQL-Anweisungen vs. gespeicherte Prozeduren 3289.5 Row-Prefetching bei Oracle 3319.6 Zusammenfassung 335

����� �"�+�$���*�+�!3�����%%����� ''�

�- *�+�!3�����%%�����0��$�+�$������������������ �''7

10.1 Entwicklung von gespeicherten Java-Programmen mit Oracle 34010.1.1 Ein Quellprogramm übersetzen 34110.1.2 Die Klassen in ein Archiv zusammenfassen 344

Page 9: Java in Datenbanksystemen

������

10.1.3 Vorher registrierte Objekte entfernen 34410.1.4 Klassen im Datenbank-Server registrieren 34510.1.5 Testen, ob die Registrierung erfolgreich war 34510.1.6 Erstellen eines Wrappers mit der CREATE FUNCTION-Anweisung 34610.1.7 Aufrufen eines gespeicherten Programms 34810.1.8 Erstellung eines Triggers mit Hilfe von Java 35510.2 Entwicklung von gespeicherten Java-Programmen mit DB2 36010.2.1 Implementierung des gespeicherten Programms 36110.2.2 Speichern der Klassen in einem Archiv und Übertragung auf den Server 36210.2.3 Aktualisieren des gespeicherten Programms 36310.2.4 Erstellung eines Wrappers 36310.2.5 Aufruf des gespeicherten Programms 36410.2.6 Gespeicherte Programme und SQLJ 36910.3 Zusammenfassung 374

���� �*�+�!��������$#$�%� '��

�� ,���0$)�(� �'��

11.1 Entwicklungsgeschichte von Cloudscape 37711.2 Cloudscape als objektrelationales DBS 37911.3 Cloudscape-Komponenten 38311.3.1 Cloudview 38411.3.2 Cloudsync 38511.3.3 Cloudconnector 38611.4 Cloudscape-Modelle 38711.4.1 Die Einbettung von Cloudscape in eine Anwendung 38811.4.2 Cloudscape im Client/Server-Modus 38911.5 Cloudscape-Archive (Bibliotheken) 39111.6 Anwendungsmöglichkeiten von Cloudscape 39111.7 Zusammenfassung 398

�� 3��� �$� �&-�

12.1 Entwicklungsgeschichte von PointBase 40112.1.1 PointBase als Datenbanksystem 40112.2 PointBase-Editionen 40312.2.1 PointBase Micro 40312.2.2 PointBase Embedded 40412.2.3 Server-Edition 40412.3 PointBase-Komponenten 40612.3.1 UniSync 40612.3.2 PointBase Server 40612.3.3 PointBase Console 40712.3.4 PointBase Commander 40812.4 PointBase-Bibliotheken 40812.5 Anwendungsmöglichkeiten von PointBase 409

Page 10: Java in Datenbanksystemen

�� ������

12.5.1 Erstellung einer Datenbank 40912.5.2 PointBase-Beispiel 40912.6 Zusammenfassung 415

�' 6������� �&��

��08� �&�7

Page 11: Java in Datenbanksystemen

erstellt von ciando

�������

Relatíonale Datenbanksysteme sind seit mehr als 25 Jahren mit Abstand die wichtigs-ten Datenbanksysteme, die in der Praxis angewendet werden. Die Gründe für die Eta-blierung dieser Systeme sind mannigfaltig: die Verwendung der standardisiertenDatenbanksprache (SQL), die hohe Portierbarkeit der Anwendungen usw. Der Sieges-zug der relationalen Datenbanksysteme hat ziemlich lange gedauert, weil sieursprünglich sehr viele Kinderkrankheiten gehabt haben. (Der größte Nachteil dieserSysteme war die schlechte Performance der Anwendungen, was im Laufe der Zeitdurch die Verfeinerung der Optimiererungstechniken ausgemerzt wurde.)

Auf der anderen Seite gibt es die Sprache Java, die erst seit einigen Jahren existiert undin dieser Zeit einen Durchbruch als Programmiersprache für viele sehr unterschied-liche Anwendungen erlebt hat. Java hat viele herausragende Eigenschaften, von denendie Rechnerunabhängigkeit und Objektorientiertheit wahrscheinlich die wichtigstensind. (Die Rechnerunabhängigkeit ermöglicht die Ausführung von Code auf entfern-ten Rechnern, was die Grundlage für die Verwendung dieser Sprache im Internet undjeder verteilten Umgebung ist.)

Obwohl diese beiden Welten verschiedene Ursprünge und Geschichten haben, koexis-tieren sie heute ausgezeichnet. Es gibt insgesamt vier Bereiche, wo sie gemeinsamangewendet werden können:

1. die JDBC-Unterstützung

2. die SQLJ-Unterstützung

3. die Implementierung der gespeicherten Prozeduren und Trigger mit Hilfe von Java

4. in Java implementierte Datenbanksysteme.

Den Anfangspunkt aller in Java geschriebenen Datenbankanwendungen stellt JDBCdar. Diese Schnittstelle kann mit Hilfe eines Treibers zu allen Zielsystemen verbundenwerden, die SQL-Anweisungen unterstützen. Abhängig vom Treiber (es gibt, genausowie bei ODBC gute und weniger gute Treiber) ist es möglich sehr aufwendige undkomplexe Datenbankanwendungen zu schreiben.

Page 12: Java in Datenbanksystemen

�� �������

Eine zweite Java-Schnittstelle für die Datenbankprogrammierung bietet SQLJ. ObwohlSQLJ eine signifikante Einschränkung gegenüber JDBC hat (mit dieser Schnittstelle istes nur möglich SQL-Anweisungen statisch d.h. zur Übersetzungszeit zu implementie-ren), wird sie sehr oft in der Praxis verwendet. Die Gründe für die Beliebtheit dieserProgrammierschnittstelle liegen sowohl in ihrer Standardisierung (durch das ISO- undANSI-Gremium) als auch in der Existenz eines gemeinsamen Vorübersetzers für alleDatenbanksysteme.

In der Welt der Programmierung der gespeicherten Prozeduren und Trigger, wo jedesDatenbanksystem eine herstellerspezifische Sprache verwendet, verspricht Java eineStandardisierung des Implementierungsverfahrens. Weil bei den meisten großenUnternehmen eine Mischung der Datenbanksysteme verschiedener Hersteller exis-tiert, wird die Verwendung von nur zwei Sprachen – Java und SQL – sicher von Vorteilsein.

Schließlich haben in Java geschriebene Datenbanksysteme einige Vorteile, die die ver-wandten Systeme nicht haben. Dazu zählen sowohl die geringe Speichergröße, die fürihr Laden notwendig ist, als auch ihre Plattformunabhängigkeit. Das PointBase-Daten-banksystem braucht z.B. bei der minimalen Ausprägung nur 64 KB Speicherplatz zumLaden, was dieses System als Wahldatenbanksystem für alle Arten mobiler Rechnerprädestiniert.

Dieses Buch führt den Leser genau in die vier oben genannten Bereiche ein. Dement-sprechend ist das Buch in fünf Teile unterteilt:

1. Einführung

2. JDBC

3. SQLJ

4. Serverseitige Java-Programmierung

5. Java-Datenbanksysteme.

Der erste Teil des Buches umfasst Kapitel 1 bis 3 und dient als Einführung sowohl inDatenbanksysteme als auch in Java. Kapitel 1 beschreibt skizzenhaft die wichtigstenKonzepte der relationalen Datenbanksysteme und führt die Beispieldatenbank ein.Kapitel 2 stellt eine Fortsetzung des ersten Kapitels dar, wo die objektorientiertenErweiterungen der im Buch verwendeten relationalen Datenbanksysteme beschriebensind. (Weil jedes Datenbanksystem verschiedene objektorientierte Konzepte unter-stützt bzw. die identischen Konzepte unterschiedlich implementiert sind, ist diesesKapitel in drei Abschnitte (für Oracle, Informix und IBM DB2) unterteilt.) In Kapitel 3werden diejenigen Eigenschaften der Java-Sprache, die für das weitere Verständnis derBuchinhalte notwendig sind, erörtert.

Page 13: Java in Datenbanksystemen

������� ��

Der zweite Teil des Buches behandelt JDBC. Dieser Teil hat drei Kapitel. Das ersteKapitel dieses Teils – Kapitel 4 – erörtert JDBC als Programmierschnittstelle für Daten-bankanwendungen. In Kapitel 5 werden objektorientierte Erweiterungen einzelnerDatenbanksysteme (Oracle und Informix) in separaten Abschnitten beschrieben unddurch Beispiele vertieft. Das letzte Kapitel dieses Teils ist der Performance der Daten-bankanwendungen, die in JDBC implementiert sind, gewidmet.

Der Aufbau des dritten Teils des Buches entspricht genau dem Aufbau des zweiten, bisauf die Tatsache, dass dieser Teil der Programmierung mit SQLJ gewidmet ist. Kapitel7 gibt allgemeine Hinweise auf die Datenbankprogrammierung mit SQLJ, währendKapitel 8 die objektorientierten Erweiterungen in Bezug auf SQLJ aufzeigt. Das letzteKapitel dieses Teils – Kapitel 9 – behandelt die Performance-Aspekte von SQLJ.

Der vierte Teil des Buches ist der Entwicklung der Datenbankobjekte (wie gespeicherteProzeduren, benutzerdefinierte Funktionen und Trigger) gewidmet. Java soll in diesemBereich der Vereinheitlichung der Implementierung der o.g. Objekte, die auf demDatenbank-Server gespeichert werden, dienen. Obwohl dieses Ziel noch immer nichterreicht ist (was auch die Unterteilung des Kapitels in separate Abschnitte für ver-schiedene Datenbanksysteme zeigt), gibt es berechtigte Hoffnung, dass eines Tages sol-che Objekte mühelos von einem Datenbanksystem zu einem anderen portiert werdenkönnen.

Der letzte Teil des Buches beschreibt zwei auf dem Markt befindliche Datenbank-systeme, die komplett in Java geschrieben sind. Kapitel 11 beschreibt Cloudscape,während Kapitel 12 das PointBase-Sytem erörtert. (Die beiden Kapitel haben densel-ben Aufbau.)

Das Buch ist als praktisches Lehrbuch gedacht. Diesem Ziel dienen sowohl zahlreicheBeispiele als auch eine sehr kleine Datenbank. Dem Leser wird empfohlen, die Bei-spieldatenbank mit dem auf unserer Internet-Seite zur Verfügung stehenden SQLJ-bzw. JDBC-Quellprogrammen zu erstellen und danach alle angegebenen Beispielenachzuvollziehen. Alle im Buch befindlichen Programme können auch von der mitge-lieferten CD-ROM geladen werden. Außerdem befinden sich auf der CD-ROM einigehilfreiche Tools, die Sharewareprogramme UltraEdit, Jeevan und MM.MySQL.

Ein großer Vorteil der in diesem Buch existierenden SQLJ- und JDBC-Programme ist,dass sie mit vier etablierten Datenbanksystemen (Oracle, MySQL, IBM DB2 und Infor-mix) ablauffähig sind. Zu diesem Zweck haben wir ein Dienstprogramm namensDBUtils erstellt, um die Zugriffe zu den o.g. Datenbanksystemen zu ermöglichen.Durch eine einfache Spezifikation des entsprechenden Datenbanksystems in jedemProgramm (z.B. DBUtils.ORACLE) ist es möglich, jedes Programm für das gewünschteZieldatenbanksystem ablauffähig zu machen. Weil verschiedene Systeme unterschied-liche Funktionalitäten in Bezug auf JDBC und SQLJ aufweisen, gibt es einzelne Pro-gramme, die nicht mit allen vier erwähnten Systemen verwendet werden können.

Page 14: Java in Datenbanksystemen

� �������

Dieses Buch wendet sich primär an alle Datenbankprogrammierer, die mit einer fort-schrittlichen Programmiersprache wie Java Anwendungen für Datenbanksystemeimplementieren wollen. Weil das Buch aus der Vorlesung »Java in Datenbanksyste-men« an der Fachhochschule Rosenheim entstanden ist, kann es genauso gut als Lehr-buch verwendet werden.

Vom Leser werden keine tieferen Kenntnisse der relationalen Datenbanksysteme undder Sprache Java erwartet; sie werden aber sicher vom Vorteil beim Lesen des Buchessein. Allen Lesern, die wenig Kenntnisse dieser beiden Säulen des Buches haben, emp-fehlen wir das genaue Studium der Kapitel 1 und 3.

An dieser Stelle möchten wir uns bei allen, die zur Entstehung dieses Buches einen Bei-trag geleistet haben, herzlich bedanken. Namentlich gilt unser Dank Herrn MartinAsbach von Addison-Wesley für die optimale Betreuung bei der Erstellung des Manu-skripts.

Alle Programme, die in diesem Buch aufgelistet sind sowie die SQLJ- bzw. JDBC-Pro-gramme für die Erstellung der Beispieldatenbank können auch auf unseren Internet-Seiten:

�������������� ��������� und ������� ����

gefunden und geholt werden.

Kommentare und Kritiken von Lesern dieses Buches sind willkommen. Bitte schickenSie sie an: ������������������ oder ��� ������ ���� .

Page 15: Java in Datenbanksystemen

������������ ��

Page 16: Java in Datenbanksystemen
Page 17: Java in Datenbanksystemen

� ������������������������������ ��

In diesem Kapitel werden die wichtigsten Datenbankbankeigenschaften beschrieben.Der erste Teil des Kapitels erörtert die Funktionalität eines Datenbankmanagement-systems. Danach wird das relationale Modell dargestellt und die in den Beispielen desBuches verwendete Datenbank erläutert. Nach einer kurzen Beschreibung des Daten-bankentwurfs werden die wichtigsten Anweisungen der SQL-Sprache durch die Bei-spiele gezeigt. Am Ende des Kapitels werden die unterschiedlichen Möglichkeitengezeigt, wie eine Datenbankanwendung programmiert werden kann.

��� �������������������

Eine Datenbank kann aus verschiedenen Blickwinkeln betrachtet werden, abhängigdavon, in welchem Zusammenhang sie gesehen wird. Aus der Sicht eines Managers istdie Datenbank eine Sammlung logisch zusammenhängender Daten, die ein Modell derAktivitäten seines Unternehmens darstellen. Aus der Sicht eines Datenbankmanage-mentsystems ist die Datenbank eine Sammlung von physikalischen Daten.

Obwohl beide Betrachtungsweisen diametral verschieden sind, haben sie etwasgemeinsam: Sie erfordern Funktionen, mit denen eine Datenbank abgefragt und modi-fiziert werden kann sowie Schnittstellen, die maschinenunabhängig sind. Alle dieseFunktionen und Schnittstellen soll ein Datenbankmanagementsystem bieten. Zusam-menfassend soll ein Datenbankmanagementsystem folgendes gewährleisten:

� logische und physikalische Datenunabhängigkeit

� prozedurale und nichtprozedurale Schnittstellen

� effiziente Abarbeitung von Datenbankoperationen

� Datenintegrität

� konkurrierender Datenzugriff

� Datensicherheit

� Datenschutz.

Page 18: Java in Datenbanksystemen

�� �������������������� ���������������������

Jede dieser Grundeigenschaften eines Datenbankmanagementsystems soll nachfol-gend erläutert werden.

����� �������������� �������������������!�������

Die logische Datenunabhängigkeit bezieht sich auf unterschiedliche logische Sichteneiner Datenbank. Einerseits existiert die logische Struktur einer Datenbank mit allendazugehörigen Objekten und Zusammenhängen, die zwischen diesen Objektenbestehen; andererseits sieht jeder Benutzer, der eine Datenbankanwendung program-miert oder benutzt, nur den für ihn relevanten Ausschnitt der gesamten logischenStruktur. Die logische Unabhängigkeit bedeutet, dass jeder Benutzer seine Sicht derDatenbank erzeugen und modifizieren kann, ohne dass die logische Gesamtstrukturgeändert werden müsste.

Unter der physikalischen Datenunabhängigkeit versteht man die Unabhängigkeit zwi-schen logischer und physikalischer Struktur einer Datenbank. Die physikalische Daten-unabhängigkeit garantiert, dass die physikalische Struktur einer Datenbank beliebiggeändert werden kann, ohne dass dadurch die logische Struktur berührt wird.

����" # �$��� ������������ �$��� ����%�����������

Bei Datenbankmanagementsystemen existieren u.a. zwei Arten von Benutzern, näm-lich der Programmierer und der Endbenutzer. Die Aufgabe eines Programmierers istes, Programme zu schreiben, mit denen eine Datenbank abgefragt oder modifiziertwerden kann. Endbenutzer sind in der Regel keine DV-Fachleute. Sie greifen auf dieDatenbank über eine leicht erlernbare Kommandosprache zu. Falls auf der Ebene die-ser Kommandosprache Kontrollstrukturen angeboten werden, wie z.B.

���������

�� ������������

�� ������������

spricht man von einer prozeduralen, ansonsten von einer nichtprozeduralen Schnitt-stelle.

Ein Programmierer hat in den meisten Fällen weitaus komplexere Aufgabenstellungenzu erledigen als ein Endbenutzer und benötigt daher nahezu immer Programmierspra-chen mit einem umfangreichen Spektrum an Kontrollstrukturen. Dementsprechendsind alle bekannteren Datenbankschnittstellen für Programmierer prozedurale Schnitt-stellen.

����& ��$�����'�� ��������� ����������� �����

Mit der Verwendung mächtiger Datenbankprogrammiersprachen wird die Entwick-lungszeit von Datenbankanwendungen in der Regel reduziert, oft allerdings auf Kosten

Page 19: Java in Datenbanksystemen

����� ���������������� ��

von zusätzlichen E/A-Operationen und längerer Verarbeitungszeit. Das Datenbank-managementsystem sollte daher für die Abarbeitung der jeweiligen Datenbankopera-tion eine optimale Strategie entwickeln können.

����( �������� ��!�

Ein Datenbankmanagementsystem sollte offensichtlich unsinnige Daten erkennen undabweisen können. (Das Datum 30. Februar oder die Uhrzeit 17:77:00 sind typische Bei-spiele.) Des weiteren ist es wünschenswert, gegenüber dem Datenbankmanagement-system Begrenzungen oder Formatangaben zu Eingabedaten deklarieren zu können,z.B.:

Jahrgang > 1959

Ausgereifte Datenbankmanagementsysteme stellen außerordentlich komplexe Mecha-nismen zur Plausibilitätsprüfung von Eingabedaten zur Verfügung. Dazu gehört ins-besondere die Fähigkeit, bereits in der Datenbank vorhandene Daten in diePlausibilitätsprüfung mit einzubeziehen.

����) *��� �� ��� �����$�� �

Der Umstand, dass im Regelfall viele Benutzer gleichzeitig auf eine Datenbank zugrei-fen, wirft eine Reihe von Problemen auf. Ein besonders gravierendes Problem wirddurch das folgende Beispiel erläutert:

1. Auf dem Konto 4711 der Bank X befinden sich 2.000,- DM.

2. Die Kunden A und B gehen in zwei verschiedene Filialen der Bank X und hebengleichzeitig 1.000,- DM vom Konto 4711 ab.

3. Die Kassierer in beiden Bankfilialen bekommen vom Datenbanksystem den Konto-stand 2.000,- DM gezeigt.

4. Beide Kassierer zahlen jeweils 1.000,- DM aus und ändern das Konto 4711 mit demWert 2.000,- DM minus 1.000,- DM gleich 1.000,- DM.

5. Es ist nun unerheblich, in welcher Reihenfolge diese beiden Änderungen ausge-führt werden; das Konto 4711 steht auf 1000,- DM statt auf 0,- DM.

Der ganze Problemkreis des konkurrierenden Datenzugriffs, der hier aufgezeigtwurde, muss von einem Datenbankmanagementsystem natürlich mit völliger Korrekt-heit abgehandelt werden. Bezogen auf das vorangehende Beispiel bedeutet dies, dassein Datenbankmanagementsystem den Kontostand von 0 DM garantieren muss, nach-dem den beiden Kunden je 1.000,- DM ausgezahlt wurden.

Page 20: Java in Datenbanksystemen

�� �������������������� ���������������������

����+ ��������� ����

Der Begriff der Datensicherheit bezieht sich auf den Ausfall von Hardware und/oderSoftware. Ein Datenbankmanagementsystem sollte in der Lage sein, nach denkbarenAusfällen die betroffenen Datenbanken automatisch in den letzten konsistenten Standzu überführen.

����, ���������$

Eine Datenbank sollte gegen unerlaubten Zugriff geschützt werden können. Wenn z.B.eine Datenbank die Gehälter der Mitarbeiter einer Firma enthält, ist es dringend not-wendig, den Zugriff auf diese Daten nur ausgewählten Benutzern zu ermöglichen.Dasselbe gilt für die sicherheitsrelevanten Daten eines Unternehmens. EntsprechendeMöglichkeiten, wie Vergabe und Entzug der Zugriffsrechte sollte jedes Datenbank-managementsystem unterstützen.

��" �������������������

Der Begriff der relationalen Datenbanken wurde 1970 von E.F.Codd eingeführt. In demArtikel »A Relational Model of Data for Large Shared Data Banks« wurde die theoreti-sche Grundlage für relationale Datenbanken festgelegt: das so genannte relationaleDatenmodell. Im Unterschied zu anderen Datenbankmanagementsystemen (netz-werkartigen bzw. hierarchischen Systemen) basiert das relationale Modell völlig aufden mathematischen Grundlagen der relationalen Algebra.

Eine Erklärung der relationalen Algebra liegt außerhalb der Ziele dieses Buches. Wirwerden die wichtigsten Eigenschaften des relationalen Modells mit Hilfe einer Bei-spieldatenbank erklären. Weiter dient die Beispieldatenbank als Grundlage für allepraktischen Beispiele innerhalb dieses Buches.

Das Grundelement einer relationalen Datenbank ist die Tabelle. Aus der Benutzersichtbesteht jede relationale Datenbank nur aus Tabellen. Eine Tabelle setzt sich aus Reihenund Spalten zusammen, d.h. sie beinhaltet keine, eine oder mehrere Reihen und eineoder mehrere Spalten. Das Objekt, das genau zu einer Reihe und einer Spalte gehört,heißt Datenwert oder Datum.

Die Beispieldatenbank, die in diesem Buch verwendet wird, enthält die Datenwerteeiner Firma, die in mehrere Abteilungen unterteilt ist. Jeder Mitarbeiter der Firmagehört einer der existierenden Abteilungen an. Die Eigenschaft unserer Firma ist, dassdie Mitarbeiter ihre Tätigkeiten in verschiedenen Projekten ausüben. Jeder Mitarbeiterkann in verschiedenen Projekten arbeiten und dabei unterschiedliche Aufgaben wahr-nehmen.

Page 21: Java in Datenbanksystemen

��������������� ����� ��

Die Datenbank besteht aus vier Tabellen:

� abteilung,

� mitarbeiter,

� projekt und

� arbeiten.

Die Tabelle abteilung stellt alle Abteilungen der Firma dar. Jede Abteilung ist auf fol-gende Weise beschrieben:

�������������������������������

abt_nr ist die für jede Abteilung der Firma eindeutige Abteilungsnummer. abt_namesteht für den Namen der Abteilung; stadt für die Stadt, in der sich diese Abteilungbefindet.

Die Tabelle mitarbeiter beinhaltet alle Mitarbeiter der Firma. Jeder Mitarbeiter ist auffolgende Weise beschrieben:

��������������������������� !�������������

m_nr kennzeichnet die für jeden Mitarbeiter eindeutige Personalnummer. m_nameund m_vorname kennzeichnen Namen und Vornamen des Mitarbeiters, währendabt_nr die Nummer der Abteilung benennt, welcher der Mitarbeiter angehört.

Die Tabelle projekt stellt alle Projekte der Firma dar. Jedes Projekt ist dabei auf fol-gende Weise beschrieben:

"�!#�$���"�����"��������������

pr_nr bezeichnet die innerhalb der Firma eindeutige Nummer des Projektes. pr_nameund mittel kennzeichnen den Namen des Projektes bzw. die Geldmittel, die für dasProjekt zur Verfügung stehen. Die Geldmittel sind in DM angegeben.

Die Tabelle arbeiten beschreibt die Beziehung zwischen den Mitarbeitern und den Pro-jekten. Diese Tabelle ist auf folgende Weise beschrieben:

���������������"���������������������

m_nr zeigt die Personalnummer des Mitarbeiters und pr_nr die Nummer des Projek-tes, in dem der Mitarbeiter arbeitet, an. Die Kombination aus m_nr und pr_nr ist inner-halb der Firma eindeutig. aufgabe beschreibt die Funktion des Mitarbeiters (mit derPersonalnummer m_nr) innerhalb des Projektes (mit der Nummer pr_nr). einst_datkennzeichnet das Eintrittsdatum des Mitarbeiters in das Projekt.

Die relationale Datenbank für das soeben beschriebene Schema ist in den Tabellen 1.1bis 1.4 dargestellt.

Page 22: Java in Datenbanksystemen

�� �������������������� ���������������������

Mit Hilfe unseres Beispiels können wir jetzt einige wichtige Eigenschaften des relatio-nalen Modells erklären:

� Die Reihen innerhalb einer Tabelle können eine beliebige Reihenfolge haben.

� Die Spalten innerhalb einer Tabelle können eine beliebige Reihenfolge haben.

������ �������� ���

��

�"

�&

-� ����

�������

. ������

/����

/����

%������ �

�� ������������ ������ ������

���� ������ ��� ����� ������

")&(0

�1�1"

�0&�+

"2&(+

�21&�

�")0�

"0))2

*����

3���

/����

# ����

/���

*����

/�$� �

3��

#�� �

4�� ����

'� ���

����

- ������

%������

�&

�&

��

�"

�"

�"

��

�� ������������ ��������� �����

����� ������� ������

��

�"

�&

'�����

4����

/� ��

�"1111�1

�2)111�1

�0+)11�1

�� ������������ ������� ����

���� ����� ������� �������

�1�1"

�1�1"

")&(0

�0&�+

"2&(+

")0�

21&�

"0))2

"0))2

21&�

"2&(+

��

�&

�"

�"

�"

�&

��

��

�"

�&

��

# �5��������

4 ���������

%������ �����

# �5��������

4 ���������

%������ �����

%������ �����

%������ �����

��6����200�

��7���202�

�)�.����200�

��7���202�

�)���$��20,�

�)�6����202�

�)�'� ��202�

��'����200�

��.����202�

�)�8�9��200�

��'� ��202�

�� �������!���� ������� ����

Page 23: Java in Datenbanksystemen

����� ���"�#�� ��

� Alle Datenwerte einer Spalte haben genau denselben Datentyp.

� Jede Spalte hat einen eindeutigen Namen innerhalb einer Tabelle. Spalten, die ver-schiedenen Tabellen angehören, können durchaus denselben Namen haben. (Bei-spiel: Die Spalte m_nr in der Tabelle arbeiten und die Spalte m_nr in der Tabellemitarbeiter.)

� Jeder einzelne Datenwert innerhalb einer Tabelle ist durch einen einzigen Wert dar-gestellt. Das heißt: In einer Reihe und innerhalb einer Spalte können sich nie meh-rere Werte gleichzeitig befinden.

� In jeder Tabelle einer relationalen Datenbank existiert ein (oder mehrere) Bezeich-ner, der jede Reihe der Tabelle eindeutig definiert. Dieser Bezeichner kann entwe-der aus einer Spalte oder aus einer Kombination mehrerer Spalten bestehen. Imrelationalen Modell heißt dieser Bezeichner Primärschlüssel. Die Spalte abt_nr istder Primärschlüssel in der Tabelle abteilung; m_nr ist der Primärschlüssel in derTabelle mitarbeiter; pr_nr ist der Primärschlüssel in der Tabelle projekt und dieKombination der Spalten (m_nr, pr_nr) ist der Primärschlüssel in der Tabelle arbei-ten. (Die Primärschlüssel der Beispieldatenbank sind grau dargestellt.)

� In einer Tabelle existieren nie zwei identische Reihen. (Diese Eigenschaft wird vonallen relationalen Datenbankmanagementsystemen nicht unterstützt.)

��& ������������

Das Datenbankdesign ist eine sehr wichtige Phase, die der Erstellung einer Datenbankvorangeht. Falls das Datenbankdesign intuitiv und ohne sorgfältige Analysephase ent-worfen wird, ist die daraus resultierende Datenbank in den meisten Fällen nicht opti-mal an die Aufgabe, zu deren Lösung sie aufgebaut wurde, angepasst. Die darausresultierende Folge kann überflüssige Datenredundanz mit damit verbundenen Nach-teilen für Speicherverbrauch und Datenkonsistenz sein.

Die Normalisierung der Daten stellt ein Verfahren dar, in dem die Datenredundanz aufder Basis der funktionalen Abhängigkeiten stufenweise reduziert werden kann. Diefunktionale Abhängigkeit gilt dann innerhalb einer Tabelle zwischen zwei Spalten(bzw. Spaltengruppen), wenn in jeder Tabellenreihe der Wert einer Spalte (Spalten-

�������

In der Terminologie relationaler Datenbanken existieren mehrere analoge Begriffe.So entsprechen die mathematischen Begriffe Relation, Tupel und Attribut in derPraxis jeweils den Begriffen Tabelle, Reihe und Spalte. Zusätzlich existieren in derPraxis weitere Begriffe wie Satz oder Record (für Reihe), Feld (für Spalte) usw. Indiesem Buch werden nur die Begriffe benutzt, die im SQL-Standard verwendetwerden, also Tabelle, Reihe und Spalte.

Page 24: Java in Datenbanksystemen

�! �������������������� ���������������������

gruppe) eindeutig durch den entsprechenden Wert der anderen Spalte (Spaltengruppe)festgelegt wird. Die funktionale Abhängigkeit wird durch einen Pfeil (A�B: »B istfunktional abhängig von A«) gekennzeichnet.

Beispiel 1.1

In der Tabelle mitarbeiter der Beispieldatenbank gilt:

�������������

weil jeder Mitarbeitername eindeutig durch die entsprechende Mitarbeiternummeridentifiziert werden kann.

Eine zweite Art der Abhängigkeit, die auch eine Rolle bei den Normalformen spielt, istdie mehrwertige Abhängigkeit. Die mehrwertige Abhängigkeit besagt, dass auf Grundeines Spaltenwertes immer die entsprechende Menge von Werten anderer Spalten ein-deutig festgelegt werden kann. Diese Art von Abhängigkeit zwischen Tabellenspaltenwird durch einen Doppelpfeil »��» gekennzeichnet.

Beispiel 1.2

��%�����&�!���

Das Attribut Autoren ist mehrwertig von dem ISBN-Code jedes Buches abhängig, weilwir auf Grund des Codes alle Autoren jedes Buches eindeutig festlegen können.

Insgesamt existieren fünf Normalformen, von welchen wir die ersten drei erläuternwerden. Die vierte und fünfte Normalform haben keine bzw. sehr geringe praktischeBedeutung. Jede Normalform ist in der nachfolgenden enthalten.

��&�� '���������3�:�����$� �8� ������� ��

Der Prozess der Normalisierung einer Datenbank sollte immer mit der ersten Normal-form beginnen. Nachdem die Datenbank die erste Normalform erfüllt, sollten dieTabellen der Datenbank so zerlegt werden, dass sie die zweite Normalform erfüllenusw. Für die meisten Datenbanken genügt die Normalisierung bis einschließlich derdritten Normalform. Die vierte und insbesondere die fünfte Normalform finden in derPraxis selten Anwendung.

Die im Zusammenhang mit der Normalisierung entscheidende Frage ist, wie viel Daten-redundanz sinnvoll ist. Diese Frage kann nur für jede Datenbank separat beantwortetwerden. Das wichtigste Kriterium für diese Entscheidung ist, ob die Datenbank wenigenoder vielen Änderungen unterworfen ist. Die Datenbanken, die wenigen oder keinenÄnderungen unterworfen sind, können problemlos mehr Datenredundanz enthalten.Demgegenüber sollten die Datenbanken, die häufig geändert werden, möglichst wenigredundante Daten haben, weil das Ziel, die redundanten Daten konsistent zu halten, imAllgemeinen nur mit hohem Aufwand zu erreichen ist.

Page 25: Java in Datenbanksystemen

����� ���"�#�� �$

��&�" � ����8� ���� �

Eine Tabelle befindet sich in der ersten Normalform, falls in jeder Reihe und für jedeSpalte nur atomare Werte existieren. Wie aus dem vorherigen Abschnitt ersichtlich,beinhaltet das relationale Datenmodell an sich schon diese Eigenschaft. Die erste Nor-malform werden wir anhand eines Ausschnitts aus der Tabelle arbeiten der Beispiel-datenbank darstellen:

Falls diese zwei Reihen folgendermaßen geschrieben würden:

würde die Tabelle arbeiten nicht in der ersten Normalform sein. (Dies ist im relationa-len Datenmodell nicht möglich.)

��&�& ;:�����8� ���� �

Eine Tabelle befindet sich in der zweiten Normalform, wenn sie keine funktionalenAbhängigkeiten von Teilen des Schlüssels enthält. Mit anderen Worten, jede Spalte die-ser Tabelle, die den Primärschlüssel nicht bildet, darf nur vom ganzen Primärschlüssel(und nicht nur von einem Teil dieses Schlüssels) funktional abhängig sein.

Nehmen wir an, dass die Tabelle arbeiten der Beispieldatenbank eine zusätzlicheSpalte mit der Nummer der Abteilung enthält:

Den Primärschlüssel dieser Tabelle bildet die Kombination der Spalten m_nr undpr_nr. Die Spalte abt_nr ist nicht voll funktional vom kompletten Primärschlüssel, son-dern schon von einem Teil (m_nr) abhängig, weil jede Abteilung, zu der ein Mitarbie-ter gehört, durch seine Personalnummer eindeutig identifiziert werden kann.

�1�1"

�1�1"

����������

��

�&

����������

�������

�������

�������

�1�1"

����������

<��=�&>

����������

��������

��������

����� ����� ������� ������� ������

�1�1"

�1�1"

")&(0

�0&�+

�����

�����

��

�&

�"

�"

���

���

# �5�������� �4 ��?

�������

%������ �����

����������

����������

��6����200�

��7���202�

�)�.����200�

��7���202�

����������

����������

�&

�&

�&

��

���

���

Page 26: Java in Datenbanksystemen

�% �������������������� ���������������������

Deswegen befindet sich die oben abgebildete Tabelle nicht in der zweiten Normalform.(Die Tabelle arbeiten der Beispieldatenbank befindet sich in der zweiten Normalform.)

��&�( � �����8� ���� �

Die dritte Normalform besagt, dass zwischen den Spalten einer Tabelle, die nicht denPrimärschlüssel bilden, keine Abhängigkeiten existieren dürfen. Ausgegangen wirddabei immer von einer Tabelle, die sich bereits in der zweiten Normalform befindet.Nehmen wir an, dass die Tabelle mitarbeiter der Beispieldatenbank eine zusätzlicheSpalte mit dem Namen der Abteilung enthält:

Der Primärschlüssel dieser Tabelle ist die Spalte m_nr. Weil die Spalten abt_nr undabt_name voneinander abhängig sind und keine von beiden Teil des Primärschlüsselsist, befindet sich die oben abgebildete Tabelle nicht in der dritten Normalform. (DieTabelle mitarbeiter, genauso wie alle anderen Tabellen der Beispieldatenbank, befindetsich in der dritten Normalform.) Datenbanken, die die dritte Normalform erfüllen, ent-halten weitgehend nicht redundante Daten.

��&�) �������� @�����������?/�����

Alle Daten einer relationalen Datenbank können theoretisch mit Hilfe einer einzigenTabelle dargestellt werden. (Eine solche Tabelle wird universelle Tabelle genannt.) DerNachteil eines solchen Datenbankentwurfs stellt die große Redundanz von Daten dar.Falls eine Datenbank z.B. alle Daten in Bezug auf Mitarbeiter und Projekte einer Firmabeinhaltet (wo z.B. jeder Mitarbeiter in verschiedenen Projekten arbeitet und jedes Pro-jekt mehrere Mitarbeiter beschäftigt), wird die Speicherung dieser Daten in einerTabelle dazu führen, dass die Tabelle sehr viele Reihen und Spalten hat. Diese Datenwerden redundant sein, was im Falle einer Änderung erhebliche Probleme aufwerfenkann.

Der Entwurf der relationalen Datenbanken funktioniert so, dass die existierenden Daten-redundanzen in den Tabellen entfernt werden, indem jede Tabelle mit redundantenDaten unterteilt wird, bis keine Datenredundanzen mehr existieren.

���� ������ ��� ����� ������ ��������

")&(0

�1�1"

�0&�+

"2&(+

�����

�����

*����

3���

/����

# ����

��������

��������

3��

#�� �

4�� ����

'� ���

��������

��������

�&

�&

��

�"

���

���

. ������

. ������

-� ����

�������

��������

��������

Page 27: Java in Datenbanksystemen

����� ���"�#�� �&

Das Grundkonzept des E/R-Modells ist die Entität, d.h. ein Objekt der realen Welt.Jede Entität hat mehrere Attribute, die spezifische Eigenschaften dieser Entität darstel-len. Abhängig von seinem Typ kann ein Attribut:

� einwertig (atomar)

� mehrwertig

� zusammengesetzt

sein.

Ein Attribut ist einwertig, falls je ein Wert für die Darstellung jeder Instanz einer Enti-tät benutzt wird. Der Familienname einer Person ist ein Beispiel eines einwertigenAttributs. (Die meisten Attribute sind einwertig.) Ein mehrwertiges Attribut kanneinen oder mehrere Werte für die Darstellung der Instanzen einer Entität haben. DerStandort einer Firma ist z.B. ein mehrwertiges Attribut, weil jede Firma einen odermehrere Standorte haben kann.

Zusammengestellte Attribute sind Attribute, die aus mehreren (voneinander unabhän-gigen) Subattributen zusammengestellt sind. Das typische Beispiel eines zusammenge-setzten Attributs ist die Adresse (einer Person oder einer Firma). Dieses Attribut ist ausmehreren einwertigen Attributen, wie PLZ, Stadt und Straße zusammengesetzt.

Das folgende Beispiel zeigt die Entität PERSON, die mehrere Attribute hat, von wel-chen das Attribut Adresse zusammengesetzt und das Attribut Vorname mehrwertigist. (Alle anderen Attribute sind einwertig.)

Beispiel 1.3

' (�)��'���������������������*+!�����,�&�����&�������'�-�����������������

Jede Entität hat ein Attribut (oder eine Kombination mehrerer Attribute), dessen Werteeindeutig für alle Instanzen sind. Ein solches Attribut wird Schlüsselattribut genannt.(In Beispiel 1.3 ist das Attribut Personal_nr das Schlüsselattribut der Entität PERSON.)

Das dritte Grundkonzept des E/R-Modells (neben Entität und Attribut) ist die Bezie-hung (relationship). Eine Beziehung existiert, falls eine Entität den Bezug auf eine odermehrere Entitäten hat. (Im spezifischen Fall kann eine Entität auch eine Beziehung mitsich selbst haben.) Die Anzahl der an einer Beziehung teilnehmenden Entitäten spezifi-ziert den Rang der Beziehung. (Die Beziehung arbeitet_ zwischen den Entitäten MIT-ARBEITER und PROJEKT (siehe Abbildung 1.1) hat z.B. den Rang 2, weil sie zweiEntitäten verbindet.)

Jede existierende Beziehung zwischen zwei Entitäten kann nur einen der drei folgen-den (Beziehungs-)Typen haben: 1:1, 1:N und M:N. Die Entitäten ABTEILUNG undMITARBEITER haben z.B. den Beziehungstyp 1:N, falls in jeder Abteilung ein odermehrere Mitarbeiter arbeiten und jeder Mitarbeiter nur einer einzigen Abteilung ange-

Page 28: Java in Datenbanksystemen

�� �������������������� ���������������������

hört. Eine Beziehung kann, genauso wie jede Entität auch Attribute haben (sieheAbbildung 1.1)

Abbildung 1.1 zeigt ein Beispiel eines E/R-Diagramms. (Ein E/R-Diagramm ist diegraphische Notation, die für die Beschreibung eines spezifischen Modells verwendetwird.) In der E/R-Notation wird jede Entität als Rechteck dargestellt, wobei der Enti-tätsname innerhalb des Rechtecks (gewöhnlich in Großbuchstaben) geschrieben wird.Attribute sind durch Ellipsen spezifiziert, und jedes Attribut ist durch eine geradeLinie mit der entsprechenden Entität (oder Beziehung) verbunden. Schließlich werdendie Rauten für die Darstellung der Beziehungen verwendet und alle Entitäten, die zueiner Beziehung gehören, werden mit ihr durch gerade Linien verbunden. Der Bezie-hungstyp jeder Entität wird auf der Verbindungslinie notiert.

.

�������

Die E/R-Notation ist nicht standardisiert. Deswegen ist die in Abbildung 1.1 ver-wendete Notation nur eine von vielen existierenden E/R-Notationen

' �"���������(�#�������#��)�*�������#

Page 29: Java in Datenbanksystemen

�������� ���#���+���,-. ��

��( ������������� �����%A�

SQL ist die standardisierte Datenbanksprache, die von allen relationalen Datenbank-systemen verwendet wird. Die Anweisungen dieser Sprache können in zwei Gruppenunterteilt werden:

� Anweisungen für Datendefinition (DDL – Data Definition Language)

� Anweisungen für Datenmanipulation (DML – Data Manipulation Language)

Folgende beide Abschnitte beschreiben die Anweisungen dieser beiden Gruppen.

��(�� %A�?':�������� ������������

Datendefinitionsanweisungen ermöglichen das Erstellen, Ändern und Löschen existie-render Datenbankobjekte. Mit Hilfe der generischen Anweisung

.( &� �!�#�$�������!�#�$�������������

können u.a. folgende Datenbankobjekte erstellt werden:

� Datenbank selbst (wird vom SQL-Standard und manchen Datenbanksystemennicht unterstützt)

� Tabelle

� Sicht

� Index.

Genauso existiert eine generische Anweisung

&�� (�!�#�$�������!�#�$�������������

mit der die Struktureigenschaften eines Datenbankobjektes geändert werden können.(Verschiedene Datenbanksysteme unterstützen die Änderung unterschiedlicher Daten-bankobjekte, wobei für alle Systeme gemeinsam ist, dass sie die Änderung einerTabelle mit Hilfe der ALTER TABLE-Anweisung ermöglichen.)

Schließlich existiert die generische Anweisung

/()'�!�#�$������

mit der ein existierendes Datenbankobjekt gelöscht wird.

Beispiel 1.4 zeigt die Erstellung der Tabelle mitarbeiter der Beispieldatenbank.

Beispiel 1.4

.( &� ��&%� ������������

���������������� 0 (��)���1���

���������������+&(.�&(�23���)���1���

Page 30: Java in Datenbanksystemen

�� �������������������� ���������������������

���������� !������+&(.�&(�23���)���1���

���������������.�&(�4���1���

��������'(�5&(6�7 6��������

Die CREATE TABLE-Anweisung in Beispiel 1.4 enthält den Namen der Tabelle (mitar-beiter) und die Definition aller Spalten, die zu dieser Tabelle gehören. Die Definitioneiner Spalte enthält u.a. den Datentyp der Spalte und die Information, ob die Spalte dieNULL-Werte zulässt oder nicht.

Bezüglich der Datentypen von Spalten gilt folgendes: Alle Datenwerte einer Spaltemüssen denselben Datentyp haben. Die SQL-Sprache kennt mehrere Datentypen, diein folgende Gruppen unterteilt werden können:

� numerische Datentypen

� alphanumerische Datentypen

� Datentypen für Datums- und/oder Zeitangeben.

Zu den numerischen Datentypen gehören u.a.: INTEGER, SMALLINT, DECIMAL undFLOAT. Die alphanumerischen Datentypen sind u.a. CHARACTER und VARCHAR(was ein Kürzel für CHARACTER VARYING ist). Zu den Datumsdatentypen gehörendie Datentypen DATETIME und TIMESTAMP.

In Beispiel 1.4 erlaubt die Spalte abt_nr den NULL-Wert, was bedeutet, dass es durch-aus möglich ist, dass für einige Mitarbeiter (z.B. bei Neueinstellungen) die zugehörigeAbteilung unbekannt ist.

Beispiel 1.5 zeigt die Verwendung der ALTER TABLE-Anweisung.

Beispiel 1.5

&�� (��&%� ��������������&//������!�����.�&(�82���1���

In Beispiel 1.5 wird eine neue Spalte (telefon_nr) der Tabelle mitarbeiter hinzugefügt.

Beispiel 1.6

/()'��&%� ������������

�������

Ein NULL-Wert ist ein spezieller Wert, der für eine Spalte zugelassen werden kann.Dieser Wert wird vorwiegend dann verwendet, wenn die Information für einenDatenwert der Spalte fehlt oder nicht bekannt ist. Er kann in einer Tabelle mit Perso-naldaten vorkommen, z.B. wenn eine Person über einen Telefonanschluss verfügt,ihre Telefonnummer aber (noch) nicht bekannt ist. In diesem Fall ist es sinnvoll, dieSpalte telefon_nr mit dem NULL-Wert zu besetzen.

Page 31: Java in Datenbanksystemen

�������� ���#���+���,-. ��

Mit der DROP TABLE-Anweisung in Beispiel 1.6 wird eine existierende Tabelle (in die-sem Fall die Tabelle mitarbeiter) gelöscht.

��(�" %A�?':�������� ���������������

Datenmodifikationsanweisungen ermöglichen das Erstellen, Ändern und Löschen exis-tierender Datenbankobjekte. Mit Hilfe der Anweisungen

� � � .�

� 1'/&�

� ��� (�

� / � �

ist es möglich, Datenwerte aus einer Datenbank auszuwählen, zu ändern und einzufü-gen. Folgende Abschnitte beschreiben alle diese Anweisungen.

���,�.�/�*'�0�#���

Mit der SELECT-Anweisung werden Datenwerte aus einer Datenbank ausgewählt. Siekönnen aus einer oder aus mehreren, miteinander verbundenen Tabellen ausgewähltwerden. Das Ergebnis einer solchen Auswahl ist erneut eine Tabelle, die keine, eineoder mehrere Reihen und eine oder mehrere Spalten hat.

Beispiel 1.7 zeigt eine einfache Form der SELECT-Anweisung.

Beispiel 1.7

Finde alle Mitarbeiterdaten, die entweder die Personalnummer 29346, oder 228559oder 25348 haben.

�������9

������!�������������

�������������������2:;4<��2=33:��23;4=�

Das Ergebnis ist:

������������������� !��������������

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

23;4=��7����������������������;

2=33:��5!���������������������8

2:;4<��'�!������&�������������2

Beispiel 1.8 zeigt die Möglichkeit, Daten aus mehreren Tabellen auszuwählen.

Beispiel 1.8

Nennen Sie Namen und Vornamen aller Projektleiter, deren Abteilung den StandortStuttgart hat.

Page 32: Java in Datenbanksystemen

�� �������������������� ���������������������

����������������� !�����

�����!�����������#!���������������!����������?�����@�����������?����

���#!�����������!�������������?�������@��������?������

���������������@A'�!#�$�������A

�������������@�A�������A

Das Ergebnis ist:

�������������������� !�����

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

����������������'����

In Beispiel 1.8 verknüpfen wir die Tabellen mitarbeiter, arbeiten und abteilung mitzwei Join-Operationen, weil die Daten aus der Tabelle mitarbeiter ausgewählt werdenund die beiden Bedingungen sich auf die Spalten aus zwei anderen Tabelle (abteilungund arbeiten) beziehen.

���12,���*'�0�#���

Mit der INSERT-Anweisung können Reihen oder Teile von Reihen in eine bestehendeTabelle eingefügt werden. Im Unterschied zu der SELECT-Anweisung kann man miteiner INSERT-Anweisung Reihen in eine einzige Tabelle einfügen.

Beispiel 1.9

����������!������������

����� �����832B8��A���A��A+�$�!�A������

Mit der INSERT-Anweisung in Beispiel 1.9 wird eine Reihe in die Tabelle mitarbeitereingefügt. Beispiel 1.10 zeigt die zweite Form der INSERT-Anweisung, mit der meh-rere Reihen gleichzeitig in eine Tabelle eingefügt werden können.

Beispiel 1.10

����������������������

��������������������4���!������

����������������������2B���!������

����������!����������������������������

������������������������������

�������������!���������

����������������������@�A5C�����A

Mit der CREATE TABLE-Anweisung in Beispiel 1.10 wird zuerst eine neue Tabelleerstellt. Die Tabelle muench_abt hat dieselben Spalten wie die Tabelle abteilung, abge-sehen von der Spalte stadt. Mit der SELECT-Anweisung, die sich innerhalb vonINSERT befindet, werden alle Reihen der Tabelle abteilung ausgewählt, deren Spaltestadt den Datenwert München hat. Diese Reihen werden anschließend in der Tabellemuench_abt eingefügt.

Page 33: Java in Datenbanksystemen

�������� ���#���+���,-. ��

Die Reihen der Tabelle muench_abt können mit der Anweisung:

�������9���!�����������

ausgewählt werden. Das Ergebnis dieser Anweisung ist:

�������������������

�>>>>>>>>>>>>>>>>>>>>>>>>>>

�8�����������%�����

�2�����������/���!��

���34�'��*'�0�#���

Die UPDATE-Anweisung ändert die Datenwerte der Reihen einer Tabelle. Ähnlich derINSERT-Anweisung kann eine UPDATE-Anweisung nur Reihen einer einzigen Tabellemodifizieren.

Beispiel 1.11

"�������������

��������������@�A0�""��������A�

���������������@�8=;8<

��������"�����@�A"2A

Mit der UPDATE-Anweisung in Beispiel 1.11 wird nur eine Reihe der Tabelle arbeitengeändert, weil die Kombination beider Bedingungen mit den Spalten m_nr und pr_nrimmer nur eine Reihe als Ergebnis liefert. (Mit anderen Worten, die Kombination derSpalten m_nr und pr_nr ist der Primärschlüssel der Tabelle arbeiten.) Im obigen Bei-spiel wurde die Aufgabe des Mitarbeiters, die bis dahin unbekannt war, definiert.

Obwohl eine UPDATE-Anweisung nur Datenwerte einer einzigen Tabelle ändert, ist esmöglich, eine andere Tabelle in der Bedingung der UPDATE-Anweisung zu verwen-den. Beispiel 1.12 zeigt das.

Beispiel 1.12

Die Aufgaben von Frau Huber sollen, wegen längerer Krankheit, in allen Projekten aufunbekannt gesetzt werden.

"�������������

��������������@����

�����������������

����������������

����������!�������������

��������������������@�A����A�

Die UPDATE-Anweisung in Beispiel 1.12 beinhaltet eine WHERE-Klausel, die eineSELECT-Anweisung enthält, d.h. eine Abfrage, die sich auf eine andere Tabelle (in die-sem Fall mitarbeiter) bezieht.

Page 34: Java in Datenbanksystemen

�! �������������������� ���������������������

�����.���*'�0�#���

Mit der DELETE-Anweisung werden Reihen aus einer Tabelle gelöscht. Im Unterschiedzu der SELECT-Anweisung kann eine UPDATE-Anweisung nur Reihen aus einer ein-zigen Tabelle löschen.

Beispiel 1.13

Löschen Sie alle Reihen der Tabelle arbeiten.

���������!����������

Die DELETE-Anweisung, genauso wie die UPDATE-Anweisung kann optional dieWHERE-Klausel enthalten. Falls die WHERE-Klausel ausgelassen wird, wie in Bei-spiel 1.13 der Fall, werden alle Reihen der genannten Tabelle gelöscht.

Folgendes Beispiel zeigt eine DELETE-Anweisung mit der WHERE-Klausel.

Beispiel 1.14

Löschen Sie die Datenwerte der Gruppenleiter aller Projekte.

���������!����������

������������������@�A0�""��������A

Die WHERE-Klausel liefert die Reihen, die aus einer Tabelle gelöscht werden. Dieexplizite Angabe von Spalten in einer DELETE-Anweisung ist nicht notwendig, weilalle Datenwerte einer oder mehrerer Reihen gelöscht werden. (Die WHERE-Klausel inder DELETE-Anweisung kann, wie bei der UPDATE-Anweisung auch, eine Unter-abfrage enthalten.)

��(�& %������<B��:�>

Eigenschaft aller Benutzertabellen ist, dass sie physikalisch existieren. Eine Benutzer-tabelle enthält also Objekte, die alle auf der Platte gespeichert sind. Im Unterschied zuBasistabellen belegen Sichten (views) keinen Speicherplatz. Sichten werden immer ausexistierenden Basistabellen abgeleitet, und das System trägt die Eigenschaften jederSicht in den Systemkatalog ein. (Für die Beschreibung des Systemkatalogs siehe dennächsten Abschnitt.) Lediglich die Einträge in verschiedenen Systemtabellen existierenphysikalisch von einer Sicht. Deswegen heißen Sichten auch virtuelle Tabellen.

Jede Sicht wird mit Hilfe der CREATE VIEW-Anweisung erstellt und mit der DROPVIEW-Anweisung gelöscht. (Manche Datenbanksysteme unterstützen auch dieAnweisung zur Änderung der Struktur einer Sicht.) Jede CREATE VIEW-Anweisungenthält eine SELECT-Anweisung, mit der die Auswahl der Reihen und Spalten ausder(n) Benutzertabelle(n) durchgeführt wird.

Page 35: Java in Datenbanksystemen

�������� ���#���+���,-. �$

Beispiel 1.15

Erstellen Sie eine Sicht, die alle Daten der Sachbearbeiter der Firma beinhaltet.

������� ���� ���������

��������������������"���������������

�������������!����������

����������������������@�A��������������A

In Beispiel 1.15 werden mit der SELECT-Anweisung die Reihen der Basistabelle arbei-ten ausgewählt, die die Bedingung in der WHERE-Klausel erfüllen. Alle ausgewähltenReihen bilden die neuerstellte Sicht v_sach_arb.

Alle Datenmanipulationsanweisungen (SELECT, INSERT, UPDATE und DELETE)können auch auf Sichten angewendet werden. Jeder Anwender, der eine Sicht benutzt,arbeitet mit ihr genau wie mit jeder anderen Basistabelle. Die Abfragen, die eine Sichtbetreffen, werden tatsächlich auf der zugrunde liegenden Basistabelle durchgeführt.(Wir erinnern noch einmal daran, dass eine Sicht physikalisch nicht existiert; es existie-ren nur Einträge in Systemtabellen, die sie definieren.) Beispiel 1.16 zeigt dies.

Beispiel 1.16

�����������

������!�� ���������

����������"�����@�A"2A

Die Abfrage aus Beispiel 1.16 wird von einem Datenbanksystem auf Grund der Defini-tion der Sicht v_sach_arb (Beispiel 1.15) in die Abfrage auf die zugrunde liegendeBasistabelle arbeiten folgendermaßen umgewandelt:

�����������

�����!����������

����������"�����@�A"2A

��������������@�A��������������A

��(�( �� �% ��������������������� ������������

Der Systemkatalog beinhaltet interne Informationen, die ein Datenbanksystem füreinen reibungslosen Ablauf benötigt. Im Systemkatalog befindet sich die Informationüber alle Datenbanken und ihre Objekte (Tabellen, Spalten, usw.). Diese Information istfür das einwandfreie Funktionieren des Systems unerlässlich. Auf Grund der gespei-cherten Information über ein Datenbankobjekt weiß das System z.B. wer der Eigentü-mer dieses Objektes ist.

Dementsprechend enthalten auch alle relationalen Datenbanksysteme einen Systemka-talog. Die Eigenschaft des Systemkatalogs eines relationalen Datenbanksystems ist,dass Metadaten (d.h. Daten über Daten), genauso wie die Basisdaten, in Tabellengespeichert sind. Damit ist es möglich, auch Metadaten mit Hilfe der SQL-Anweisun-gen abzufragen und falls notwendig, zu ändern.

Page 36: Java in Datenbanksystemen

�% �������������������� ���������������������

Jedes kommerzielle Datenbanksystem hat eine Sammlung von Systemtabellen, die sichin ihren Namen und ihrer Bedeutung unterscheiden. Zum Beispiel ist schon der Begriffdes Systemkatalogs bei den unterschiedlichen Datenbanksystemen verschieden:INFORMIX nennt seinen Systemkatalog system catalog, während ORACLE vom datadictionary spricht. (Genauso verwendet IBM DB2 einen anderen Begriff für den System-katalog: catalog tables.)

Genauso unterscheiden sich die Namen einzelner Tabellen bei verschiedenen Daten-banksystemen: Während INFORMIX und IBM DB2 eine Systemtabelle namens sys-tables enthalten, die Informationen über Tabellen einer Datenbank speichert, hatORACLE drei Tabellen mit dem entsprechenden Inhalt: user_tables, all_tables unddba_tables. (Zusätzlich dazu, stellen diese drei Oracle-Tabellen Sichten dar.)

Beispiele 1.17 und 1.18 zeigen zwei identische Abfragen auf den Systemkatalog vonInformix bzw. Oracle. Obwohl beide Beispiele alle Daten der Tabelle mitarbeiter ausdem Sytemkatalog abfragen, zeigen die beiden SELECT-Anweisungen signifikanteUnterschiede.

Beispiel 1.17 (Informix)

� � .��9��()5��D�������

�����E� ( ���������@�A�����������A

Beispiel 1.18 (Oracle)

� � .��9��()5�����!�#����

�����E� ( �!�#���������@�A5��&(% �� (A

Das SQL-Standardisierungsgremium hat das Informationsschema konzipiert, damiteine einheitliche Oberfläche existiert, mit der Systemkataloge aller Datenbankherstellerabgefragt werden können. Dieses wird im nächsten Abschnitt beschrieben.

1�������##+����

Das Informationsschema wurde ursprünglich im SQL92-Standard eingeführt, mit derAbsicht eine einheitliche Schnittstelle einzuführen, die dann den Zugriff von einemDatenbanksystem auf den Systemkatalog eines anderen ermöglicht. Es besteht ausSichten, die die gesamte Information über Datenbankobjekte (Tabellen, Spalten usw.)liefern. (Diese Sichten können vom Benutzer nicht geändert werden.) Im Unterschiedzu den Systemtabellen des Systemkatalogs, die die Metadaten eines Systems enthalten,verwaltet das Informationsschema die Umgebung einer Datenbank.

Die folgenden Unterabschnitte beschreiben die beiden wichtigsten Sichten, die zumInformationsschema gehören.

Page 37: Java in Datenbanksystemen

�������� ���#���+���,-. �&

����� ���������� �����

Die Sicht information_schema.tables enthält eine Reihe für jede Tabelle der aktuellenDatenbank, zu der der Benutzer Zugriff hat. Die wichtigsten Spalten dieser Sicht sind:

������������ �����������

Die Sicht enthält eine Reihe für jede Spalte der aktuellen Datenbank, zu der der Benut-zer Zugriff hat. Die wichtigsten Spalten dieser Sicht sind:

��(�) 4�������� ���# �$��� �

Gespeicherte Prozeduren haben Ähnlichkeiten mit den Funktionen, die in einer proze-duralen Programmiersprache programmiert sind. Sie werden ähnlich wie alle anderenDatenbankobjekte mit Hilfe einer Datendefinitionsanweisung erstellt und als Objekteder Datenbank gespeichert. Diese Anweisung heißt CREATE PROCEDURE und sieermöglicht die Speicherung der Prozedur im Datenbank-Server. (Mit der DROP PRO-CEDURE-Anweisung wird eine erstellte Prozedur gelöscht.)

Jede Prozedur kann sowohl SQL- als auch prozedurale Anweisungen enthalten. Dieprozeduralen Anweisungen entsprechen den spezifischen Erweiterungen der SQL-Sprache beim einzelnen Datenbanksystemen.

������ �����������

�����C������� �� �8��������*��������<�� ��������>=�$����������%��������D ��

�����C������ �� �8��������%������=�$����������%��������D ��

�����C��� �� ������������

�����C� �� �� ��������� ��<���E-'%���'-��F���� �EB��GF����>�

������ �����������

�����C������� �� �8��������*��������<�� ��������>=�$����������%��������D ��

�����C������ �� �8��������%������=�$����������%��������D ��

�����C��� �� ������������

�����C��� �� �%���������

� ����C������� �������������������� ��� �%������

����C� �� �� ������ ���� �%������

�������

Obwohl gespeicherte Prozeduren seit 1995 vom SQL-Gremium standardisiert sind,haben alle Datenbankhersteller ihre eigenen prozeduralen Erweiterungen. Deswe-gen ist die Erstellung der gespeicherten Prozeduren herstellerspezifisch und auch

Page 38: Java in Datenbanksystemen

�� �������������������� ���������������������

Jeder gespeicherten Prozedur können Daten als Parameter zugewiesen werden. DieÜbergabe der Parameter wird beim Prozeduraufruf durchgeführt. Prozeduren könnenauch einen Rückgabewert übergeben, der die Information über die erfolgreiche Aus-führung der Prozedur bzw. über einen aufgetretenen Fehler liefert.

Gespeicherte Prozeduren werden übersetzt, bevor sie in der Datenbank gespeichertwerden. Damit wird für jede Prozedur immer ein Ausführungsplan gespeichert, derbei der Ausführung der Prozedur benutzt wird. Diese Vorgehensweise bringt für oftverwendete gespeicherte Prozeduren einen entscheidenden Performance-Vorteil: Diewiederholte Übersetzung der Prozedur kann eliminiert und damit ihre Ausführungwesentlich beschleunigt werden.

Das o.g. Verfahren bei der Übersetzung und Ausführung von gespeicherten Prozedu-ren bringt auch einen anderen Vorteil: Die Anzahl der Zugriffe zwischen den Anwen-dungsprogrammen einerseits und dem Datenbank-Server andererseits lässt sichwesentlich reduzieren, indem man eine SQL-Anweisungsfolge in der Form einergespeicherten Prozedur schreibt, anstatt SQL-Anweisungen einzeln zu benutzen.(Diese Eigenschaft der gespeicherten Prozeduren ist besonders vorteilhaft, wenn derDatenbank-Server und die Datenbankanwendung entfernt voneinander sind).

Die Verwendung von gespeicherten Prozeduren kann weitere Vorteile mit sich brin-gen:

� gespeicherte Prozeduren bieten die Möglichkeit, den Zugriff auf eine Tabelle einzu-schränken, indem alle Änderungen der Tabellendaten mit Hilfe einer einzigen Pro-zedur durchgeführt werden.

� Alle Anwendungsprogramme, die das entsprechende Zugriffsrecht haben, könnenProzeduren gemeinsam verwenden, anstatt denselben Code einzeln in jedem Pro-gramm zu enthalten. Dadurch werden die Programmierung und die Verwendungder existierenden Ressourcen effizienter.

Die Verwendung von gespeicherten Prozeduren kann unter Umständen auch einenNachteil haben: Prozeduren sind in Systemtabellen, die sich im Allgemeinen auf derPlatte befinden, gespeichert. Bevor sie zum ersten Mal in einer Anwendung benutztwerden können, müssen sie in den Arbeitsspeicher geladen werden.

Mit der Anweisung EXECUTE PROCEDURE kann eine existierende Prozedur ausge-führt werden. (Um eine gespeicherte Prozedur ausführen zu können, muss der Benut-zer ihr Eigentümer sein oder das entsprechende Ausführungsrecht haben.

die einfachsten Prozeduren, die für ein System implementiert sind, müssen für einanderes System umgeschrieben werden.

Page 39: Java in Datenbanksystemen

����� �����0��"����������������� ��

��) ��������:������� �� ����� �

Datenbankanwendungen können auf zwei unterschiedliche Arten implementiert wer-den. Die erste Schnittstelle wird oft Host Language Interface (HLI) genannt, weil dabei dieSQL-Anweisungen in einer Host-Sprache eingebettet werden. Diese Schnittstelle wirdoft die eingebettete SQL-Sprache genannt. Bei dieser Schnittstelle wird ein Vorüberset-zer zur Verfügung gestellt, der jede SQL-Anweisung in die Hostsprache übersetzt.Damit wird, nach der Vorübersetzerphase, ein Programm erzeugt, das anschließendübersetzt werden kann.

Prozedurale Programmiersprachen können auch auf eine andere Weise verwendetwerden, um Datenbankanwendungen zu erstellen. Diese zweite Methode heißtSchnittstelle mit Bibliotheksaufrufen (Call Level Interface – CLI) und charakterisiert dieExistenz einer oder mehrerer Bibliotheken, deren Funktionen von einem Programmaufgerufen werden. (Das Programm wird immer mit Hilfe einer prozeduralen Pro-grammiersprache implementiert.) Die übersetzten und in der Bibliothek gespeichertenFunktionen stellen damit eine weitere Schnittstelle zum Datenbanksystem dar.

��+ ;�����������

Ein relationales Datenbankmanagementsystem gewährleistet u.a.:

� logische und physikalische Datenunabhängigkeit

� prozedurale und nichtprozedurale Schnittstellen

� effiziente Abarbeitung von Datenbankoperationen

� Datenintegrität

� konkurrierenden Datenzugriff

� Datensicherheit

� Datenschutz.

Die SQL-Sprache ist die standardisierte Datenbanksprache, mit der auf Daten einesrelationalen Datenbanksystems zugegriffen werden kann. Die Anweisungen dieserSprache können in Datendefinitions- (DDL) und Datenmanipulationsanweisungen(DML) unterteilt werden. Die CREATE TABLE-Anweisung stellt das Beispiel einerDDL-Anweisung dar, während SELECT, INSERT, UPDATE und DELETE vier generi-sche DML-Anweisungen sind.

Das nächste Kapitel beschreibt die objektorientierten Erweiterungen der relationalenDatenbanksysteme Oracle, Informix und IBM DB2.

Page 40: Java in Datenbanksystemen
Page 41: Java in Datenbanksystemen

� �������������� ����������������������������������

Relationale Datenbanksysteme haben in all den Jahren, in denen sie benutzt wurden,ihre Tauglichkeit für den produktiven Einsatz unter Beweis gestellt, und sind deswe-gen mit Abstand die wichtigsten Datenbanksysteme der achtziger und neunziger Jahregewesen. Trotz dieses Erfolgs haben sie auch einige Schwächen, die teils als Schwächendes relationalen Modells gelten und teils als Schwächen ihres ursprünglichen Ent-wurfs. Die wichtigste Schwachstelle ist, dass objektorientierte Konzepte von relationa-len Datenbanksystemen nicht unterstützt werden.

Alle auf dem Markt befindlichen Hersteller der relationalen Datenbanksysteme habensich in den letzten Jahren bemüht diese Schwächen zu beheben und die meisten objekt-orientierten Konzepte zu implementieren.

Obwohl in der Zwischenzeit auch der SQL-Standard (SQL99) objektorientierte Erwei-terungen in die SQL-Sprache übernommen und sie festgelegt hat, gilt für alle Daten-bankhersteller, dass sie wenig Gemeinsamkeiten bei der Implementierung dieserKonzepte haben. Aus diesem Grund ist es unmöglich, eine Beschreibung dieser Kon-zepte für alle existierenden Datenbanksysteme zu machen (wie wir für die SQL-Spra-che in Kapitel 1 gemacht haben). Deswegen wird dieses Kapitel in mehrere Abschnitteunterteilt, und jeder Abschnitt wird einem spezifischen Datenbanksystem gewidmet.

Der erste Abschnitt dieses Kapitels beschreibt die objektorientierten Erweiterungen beiOracle, während der zweite Teile dieselben Erweiterungen bei Informix erläutert. Imletzten Teil des Kapitels werden objektorientierte Erweiterungen von IBM DB2 skiz-ziert. (Wir werden uns mit den objektorientierten Erweiterungen dieses Systems nichtausführlich befassen, weil die Firma IBM diese Funktionalität noch nicht in die JDBC-Schnittstelle bzw. SQLJ implementiert hat.)

��� ��������������� ������������������

Oracle hat folgende Erweiterungen, die in Bezug zur Objektorientierung stehen:

� der Objekttyp

� der Datentyp REF (Objektreferenzen)

� Kollektionen.

Alle diese Erweiterungen werden in den nachfolgenden Unterabschnitten beschrieben.

Page 42: Java in Datenbanksystemen

�� � �������������� ���������� ��������� ����������

����� ������������

Seit Version 8 unterstützt Oracle benutzerdefinierte Datentypen mit Hilfe einesModells, das die Firma Oracle Typsystem (type system) nennt. Dieses Typsystem gibtdem Benutzer die Möglichkeit, neue Datentypen mit Hilfe der herkömmlichen Stan-darddatentypen, existierenden benutzerdefinierten Datentypen, Objektreferenzen undKollektionen zu definieren. (Die einzige Gruppe von Datentypen, die Oracle vor derEinführung der benutzerdefinierten Datentypen unterstützt hat, waren Standard-datentypen wie INTEGER, CHARACTER, FLOAT usw.)

Benutzerdefinierte Datentypen werden bei Oracle mit Hilfe des Objekttyps definiert.Ein Objekttyp ist ein einheitlicher Mechanismus, mit dem die Struktur und das Verhal-ten eines benutzerdefinierten Datentyps definiert werden kann. (Unter der Struktureines Typs verstehen wir alle Attribute, die diesen Typ beschreiben. Das Verhalteneines Typs umfasst alle Operationen (Methoden), die auf einzelne Instanzen des Typsangewendet werden können.)

Ein Objekttyp wird bei Oracle mit Hilfe der CREATE OBJECT TYPE-Anweisung defi-niert. Die Syntax dieser Anweisung sieht folgendermaßen aus:

�������������� ���������������������������� ������� ��������� �������� ��������

attr_name ist der Name eines Attributes, während datentyp seinen Datentyp kenn-zeichnet. Beispiel 2.1 zeigt die Erstellung eines einfachen Objekttyps.

Beispiel 2.1

������������ ��������������� �� ����!���"���#$%��&'� ����!���"����$%%(

In Beispiel 2.1 wird ein neuer Datentyp namens name_t erstellt. Dieser Datentypbesteht aus zwei Elementen, die beide mit Hilfe des Standarddatentyps VARCHARdefiniert sind. (Ein Typ wie name_t, der mehrere Komponenten verschiedener Daten-typen zu einem neuen Datentyp zusammenfasst, wird auch Tupel bzw. Reihentypgenannt.)

Die CREATE OBJECT TYPE-Anweisung erstellt im Grunde nur eine Schablone (ähn-lich der struct-Anweisung in der Sprache C), aber keine Instanz dieses Typs wurde bisjetzt erstellt. Um dies zu erreichen, muss eine Tabelle erstellt werden, deren Spalten(oder Reihen) Instanzen diesen Typs enthalten. Dies wird mit Hilfe der herkömmlichenCREATE TABLE-Anweisung durchgeführt. Beispiel 2.2 zeigt die Erstellung einerTabelle, deren Spalte mit Hilfe des oben definierten Typs deklariert ist.

Beispiel 2.2

����������)���'*� �������������'*� �+��,-��� ���� ��������.��,-�%(

Page 43: Java in Datenbanksystemen

�������������� ���������� �� ������ ��

In Beispiel 2.2 wurde eine Tabelle erstellt, deren Spalte name mit Hilfe des benutzer-definierten Typs name_t (Beispiel 2.1) deklariert ist.

Die Tabelle dozent ist leer. Um einzelne Reihen in diese Tabelle einzufügen, wird dieINSERT-Anweisung verwendet, die in die Spalte name Instanzen des Typs name_t ein-fügt. Beispiel 2.3 zeigt dies.

Beispiel 2.3

,-�����,-����'*� ������!�)/����0�#1�� �����23.�*2���2"�45�2%��0�$%(

Wie aus Beispiel 2.3 ersichtlich, wird der Wert der zweiten Spalte (name) so eingefügt,dass der Typ name_t zuerst angegeben wird, um zu spezifizieren, dass es sich beimEinfügen um eine Instanz dieses Typs handelt. Die Form

name_t(’Kurz’, ’Helga’)

die eine Instanz eines Typs aus den einzelnen Attributen bildet, wird generell Objekt-konstruktor genannt.

Um die Attribute eines Objektkonstruktors anzusprechen, wird die sogenannte Punkt-notation (dot notation) verwendet. Beispiel 2.4 zeigt die Abfrage auf die Tabelle dozent,wo u.a. auch der Nachname des Dozenten ermittelt wird.

Beispiel 2.4

Finde die Nummer und den Nachnamen des Dozenten, der im Raum 120 beherbergtist.

��)�������'*� �+����� ���� �� �������6��7��'*� ���8"��������.��90�$(

In Beispiel 2.4 wird für den Nachnamen des Dozenten die doppelte Punktnotation ver-wendet: Der erste Punkt indiziert, dass es sich bei name um eine Spalte der Tabelledozent handelt (d ist der Aliasname dieser Tabelle). Der zweite Punkt spezifiziert, dasses sich bei nachname um ein Attribut des Objekttyps name_t handelt.

Ein Objekttyp kann benutzt werden, um einen anderen (komplexeren) Objekttyp zudefinieren. Beispiel 2.5 zeigt die Erstellung eines solchen Objekttyps.

�������

Bei der Verwendung der Objekttypen und der Punktnotation soll immer der Alias-name für die entsprechende Tabelle benutzt werden. Oracle verlangt dies (obwohlin manchen Fällen auch die Vermeidung der Aliasnamen in einer Anweisung zuihrer korrekten Ausführung führt).

Page 44: Java in Datenbanksystemen

�� � �������������� ���������� ��������� ����������

Beispiel 2.5

���������������:' �������������������:' �+��,-������� ���� �����������4����4:�;� ���,-�%(

Der Objekttyp person_t verwendet den Typ name_t für die Definition eines seinerAttribute (name). Die Voraussetzung für die Definition eines Objekttyps mit Hilfeeines einfacheren Typs ist die Existenz des zweiten. Das heißt, dass der Typ person_t inBeispiel 2.5 nur erstellt werden kann, falls der Typ name_t schon existiert.

Die Verkettung mehrerer Objekttypen, wo der nächste immer auf der Basis des vorhe-rigen (wie im Beispiel 2.5) definiert ist, hat Konsequenzen beim Löschen eines Typs.Generell wird ein Objekttyp mit Hilfe der DROP TYPE-Anweisung gelöscht. Falls abereine Kette von Abhängigkeiten zwischen mehreren Objekttypen existiert, muss zuerstder zuletzt definierte (der komplexeste) Objekttyp gelöscht werden und danach, derReihe nach die anderen. Bezogen auf Beispiel 2.5 heißt das, dass zuerst der Objekttypperson_t gelöscht werden muss, bevor der Typ name_t entfernt werden kann. (DieInformation über die Abhängigkeiten zwischen den existierenden Objekttypen wirdbei Oracle in entsprechenden Systemtabellen gespeichert.)

Wie wir schon erläutert haben, kann ein Objekttyp nicht nur für die Definition einerTabellenspalte (wie in den Beispielen 2.2 bzw. 2.5 der Fall ist) verwendet werden. Einsolcher Typ kann auch für die Erstellung einer sogenannten Objekttabelle (object table)verwendet werden. Eine Objekttabelle ist eine Tabelle, deren Instanzen dem darunter-liegenden Objekttyp entsprechen. Beispiel 2.6 zeigt die Erstellung der Objekttabellepersonen.

Beispiel 2.6

����������)�����:' � ��6����:' ��������,7����3������:' �+�%%(

Die CREATE TABLE-Anweisung in Beispiel 2.6 erstellt eine Tabelle personen, die aufdem Objekttyp person_t (Beispiel 2.5) basiert. Wie aus Beispiel 2.6 ersichtlich, könnenIntegritätsregeln (wie PRIMARY KEY, CHECK usw.) ausschließlich für eine Objekt-tabelle definiert werden. Mit anderen Worten können solche Integritätsregeln nicht mitder entsprechenden CREATE TYPE-Anweisung angegeben werden, was auch naheliegend ist, weil eine CREATE TYPE-Anweisung nur eine Schablone definiert, aufderen Grundlage dann viele unterschiedliche Objekttabellen (falls notwendig) erstelltwerden können.

Beispiel 2.7 zeigt, wie Reihen der Tabelle personen eingefügt werden können, währendTabelle 2.1 den Inhalt dieser Tabelle nach dem Einfügen widerspiegelt.

Page 45: Java in Datenbanksystemen

�������������� ���������� �� ������ ��

Beispiel 2.7

,-�����,-������:' � �!�)/���0�#1<�� �����23.�*2���2"�45�2%��0=%(,-�����,-������:' � �!�)/����#1<>�� �����2)� 52���2�'2%��=$%(,-�����,-������:' � �!�)/���#1<>?�� �����2"�.@2���2� �2%��1<%(

Die Syntax einer UPDATE-Anweisung, die sich in ihrer SET-Klausel auf einen Objekt-typ bezieht, sieht analog der Syntax der INSERT-Anweisung (siehe Beispiel 2.3) aus.Beispiel 2.8 zeigt eine solche UPDATE-Anweisung.

Beispiel 2.8

/�A�������:' � ������������9����:' ��0�#1<>?=B�� �����2)� 52��2� �2%��#�%����8"�������:' �+��9�B=?><1#�0(

In Beispiel 2.8 wird eine ganze Reihe der Tabelle personen auf Grund der Bedingungin der WHERE-Klausel ersetzt. (Oracle erlaubt sogar den Wert eines Primärschlüsselszu ersetzen, wie in Beispiel 2.8 ersichtlich ist.)

����� �����������

Kollektionen haben gewisse Ähnlichkeiten mit den schon beschrieben Objekttypen. ImUnterschied zu den Objekttypen, die generell mehrere Elemente verschiedener Daten-typen haben, enthalten Kollektionen immer Elemente desselben Datentyps. (Objekt-typen und Kollektionen werden gemeinsam Typkonstruktoren genannt, weil mit ihrerHilfe komplexere Datentypen erstellt werden können.)

Zu den Kollektionen gehören generell:

� Menge (set)

� Multimenge (multiset bzw. bag)

� Liste (list)

� Vektor (array)

� geschachtelte Tabellen (nested tables bzw. table type).

Ein Mengenkonstruktor erzeugt aus mehreren Elementen eines zugrunde liegendenTyps einen neuen Typ. (Der zugrunde liegende Typ heißt Elementtyp und kann ein

�������� ��� � ����������

��� ! ��"#�$���� �%

�� !& '���#����� %(

� !&) $���#�*��� !

������� �� ! ������������� ������� �� ��� "�#�

Page 46: Java in Datenbanksystemen

�$ � �������������� ���������� ��������� ����������

Standarddatentyp, ein Typkonstruktor oder ein benutzerdefinierter Datentyp sein.)Die Elemente einer Menge haben keine Ordnung. Eine Menge enthält keines der Ele-mente mehrfach. Ein Multimengenkonstruktor entspricht einem Mengenkonstruktorbis auf eine Ausnahme: die mehrfache Erscheinung einzelner Elemente ist erlaubt.

Im Unterschied zu den Kollektionen Menge und Multimenge hat eine Liste geordneteElemente und kann ein Element mehrfach enthalten. Damit existieren bei einer Listedas erste Element, das zweite usw., während bei Mengen und Multimengen solcheKlassifizierung der Elemente nicht möglich ist.

Ein Vektor (array) ist bis auf einen Unterschied identisch mit dem Kollektionstyp Liste.Im Unterschied zu Liste hat Vektor eine konstante Anzahl von Elementen. Einegeschachtelte Tabelle ist diejenige Tabelle, die in einer anderen Tabelle anstelle einesDatenwertes erscheint. (Die Unterstützung der geschachtelten Tabellen verletzt dieerste Normalform des relationalen Datenmodels.

Von allen oben genannten Kollektionen unterstützt Oracle die letzten beiden: Vektorenund geschachtelte Tabellen.

%������

Der Kollektionstyp Vektor wird bei Oracle mit Hilfe des Datentyps VARRAY (varying-length array) definiert. Jeder mit VARRAY definierte Vektor hat einen Namen, denDatentyp der Elemente und die maximale Anzahl von Elementen, die dieser enthaltenkann. (Die tatsächliche Anzahl der Elemente entspricht nicht unbedingt der maxima-len Angabe, genauso wie das beim Datentyp VARCHAR ist, wo die tatsächlicheAnzahl von alphanumerischen Zeichen kleiner oder gleich dem angegebenen Wert ist.)Alle Elementwerte eines Vektors werden bei Oracle in den meisten Fällen physikalischmit den anderen Spalten der entsprechenden Reihe gespeichert.

Die Erstellung eines Vektors wird ähnlich der Erstellung eines Objekttyps durchge-führt. Der einzige Unterschied ist, dass anstelle der CREATE OBJECT TYPE-Anwei-sung die CREATE VARRAY TYPE-Anweisung verwendet wird.

Beispiel 2.9 zeigt die Verwendung der CREATE VARRAY TYPE-Anweisung.

Beispiel 2.9

������������� ���&��������!������>%��6��"���#$%(����������)��C+������������� �����"���#$%�����������'���� ���&�����%(

In Beispiel 2.9 wird zuerst ein Vektor namens char_varray mit Hilfe der CREATEVARRAY TYPE-Anweisung erstellt. Dieser Typ wird dann in der zweiten SQL-Anweisung (CREATE TABLE) für die Definition der Spalte orte verwendet.

Page 47: Java in Datenbanksystemen

�������������� ���������� �� ������ �&

Die Tabelle firma ist leer. Um einzelne Reihen in diese Tabelle einzufügen wird dieINSERT-Anweisung mit den Objektkonstruktoren verwendet, die wir schon in Beispiel2.3 benutzt haben. Beispiel 2.10 zeigt, wie Reihen in die Tabelle firma eingefügt werdenkönnen.

Beispiel 2.10

,-�����,-���C+����!�)/����2�782��� ���&�����27D � � 2�2, 5'4:��2�2E@��:��2%%(,-�����,-���C+����!�)/����2�.�+2��� ���&�����2�.5��2�2A+ 5'4C+ 52�2, �+� 2%%(,-�����,-���C+����!�)/����27+:.@+: +2��� ���&�����2�'F+'2�2)' �' 2�2"��@.�52%%(

Wie aus Beispiel 2.10 ersichtlich, werden die Elemente der VARRAY-Spalte mit Hilfedes Konstruktors char_varray eingefügt.

Eine Abfrage auf die Spalte vom Typ VARRAY wird auf übliche Art und Weise durch-geführt. Beispiel 2.11 zeigt die Abfrage auf die Tabelle verzeichnis.

Beispiel 2.11

��)����C� ����C�'�������������6��7�C+����C

Ein einzelnes Element eines Vektors kann bei Oracle nicht direkt (d.h. mit Hilfe derinteraktiven SQL-Sprache) abgefragt werden. Dies kann nur mit Hilfe der existieren-den Programmierschnittstellen durchgeführt werden (siehe Beispiel 5.2).

Beispiel 2.12 zeigt die Änderung einer VARRAY-Spalte.

Beispiel 2.12

/�A����C+�������������'���9�� ���&�����2�'F+'2��2)' �' 2��2"��@.�52��2���+:2%������8"���� ����9�27+:.@+: +2

In Beispiel 2.12 wird die Anzahl der Standorte des Autoherstellers Mitsubishi umeinen neuen (Paris) erweitert. Die UPDATE-Anweisung verwendet den Objektkon-struktor, um den neuen Standort (zusammen mit der Liste aller existierenden Stand-orte) anzugeben.

'���#��#����� �������

Eine geschachtelte Tabelle stellt genau das dar, was ihr Name sagt, nämlich die Schach-telung einer Tabelle innerhalb einer anderen. Damit ist die geschachtelte Tabelle eineKollektion, deren Elemente Tabellen sind.

Die geschachtelten Tabellen werden mit Hilfe der herkömmlichen CREATE TABLE-Anweisung erstellt, wobei diese Anweisung als Erweiterung die NESTED TABLE-

Page 48: Java in Datenbanksystemen

�( � �������������� ���������� ��������� ����������

Klausel enthalten kann. Mit dieser Klausel kann die geschachtelte Tabelle separat, d.h.physikalisch getrennt von der Basistabelle gespeichert werden.

Die Syntax der NESTED TABLE-Klausel sieht folgendermaßen aus:

-����A����)��:��4� � ��������������@�44� � ���

Beispiel 2.13 zeigt die Erstellung einer geschachtelten Tabelle.

Beispiel 2.13

������������&��G� ����������)���6����:' �(����������)����@�+����������������@� ��,-�����������������:' �4+� ����:' ��������������&��G� ���&��G� ���������������,7����3�����@� �%%��������-����A����)��&��G� ������������&����@�44�(

In Beispiel 2.13 wird zuerst eine Objekttabelle namens verwandte_t erstellt. DieseTabelle wird als Typ der Spalte verwandte in der Tabelle arbeiter verwendet. Damitenthält die Spalte verwandte alle Verwandten eines Arbeiters in der Tabellenform.

Die Tabelle arbeiter ist leer. Um die Reihen in diese Tabelle einzufügen, muss dieINSERT-Anweisung, die in Beispiel 2.14 angegeben ist, verwendet werden.

Beispiel 2.14

,-�����,-�����@�+���!�)/���0�#1<����:' ��0�#� �����27.�44��2�2"� :2%�#1%��&��G� �������:' ��0�1�� �����27.�44��2�26�� *2%��01%�������:' ��0�<�� �����27.�44��2�2� �+:+ �2%���B%%%,-�����,-�����@�+���!�)/�����#1<0�����:' ���#0�� �����2�� �+���2�2H�'�52%��1=%��&��G� �������:' ���#��� �����2�� + �4��2�27� .�4�2%��<>%������:' ���##�� �����2�.� �.��2�2".@��2%��1�%%%,-�����,-�����@�+���!�)/����#1<0������:' ��#0��� �����2".@��2�2"�45�2%��>=%��&��G� �������:' ��#0#�� �����2�� . �� 2�2��+F2%���>%������:' ��#01�� �����27�*5��2�2A� +�4�2%��<?%%%

Um die Daten aller Verwandten eines Arbeiters einzufügen, wird in Beispiel 2.14 derTypkonstruktor verwandte_t in jeder INSERT-Anweisung einmal verwendet. Nachder Angabe dieses Konstruktors wird für jeden einzelnen Verwandten der Typkon-struktor person_t benutzt.

Page 49: Java in Datenbanksystemen

�������������� ���������� �� ������ �)

Tabelle 2.2 zeigt den Inhalt der Tabelle arbeiter nach der Ausführung des Beispiels2.14.

Beispiel 2.15 zeigt, wie man mit einer INSERT-Anweisung Reihen der geschachteltenTabelle einfügen kann.

Beispiel 2.15

,-�����,-������)������)������&��G� ���6��7���@�+�����8"��������@� ��9�2�#1<02%�����!�)/�������:' ��#0#�� �����2�� . �� 2�2��+F2%���>%%

INSERT in Beispiel 2.15 stellt eine Erweiterung der Grundform dieser Anweisung dar.Anstelle der Tabellennamen erscheint in dem obigen Beispiel eine SELECT-Anwei-sung, die die geschachtelte Tabelle (d.h. die Verwandten) des Mitarbeiters mit der Per-sonalnummer 23451 wählt. Nach der Festlegung der geschachtelten Tabelle wirddieser eine neue Reihe:

�#0#�� �����2�� . �� 2�2��+F2%���>%

hinzugefügt.

Beispiel 2.16 zeigt eine Abfrage auf die geschachtelte Tabelle.

Beispiel 2.16

��)����&��G� ��������6��7���@�+���8"������@� ��9��#1<0

Diese Abfrage listet eine Zeile für den Mitarbeiter mit der Personalnummer 23451 auf,mit allen seinen Verwandten, die in einer zusätzlichen Spalte als skalarer Wert erschei-nen.

Beispiel 2.17 zeigt eine weitere Form der Abfrage auf geschachtelten Tabellen.

����� ���������� ����� �

���#�+,�����#$���-#�� �� #�+,����#�.��"-#��

��� ! ��!#�+,�����#�/0����-#��1

� !�� ���#�+$���#�$����-#�&% ���#�+��0�0����#� �-#��&

�� #�+,��"��#�������-#�!)

������� ���! *���+� ,�� ������� ����� �� ,�� ����#��#����� ������� 2����3��

Page 50: Java in Datenbanksystemen

�- � �������������� ���������� ��������� ����������

Beispiel 2.17

��)������@� ����6��7���@�+��������8"����#�I����)������/-��J%�6��7����)����&��G� ��%%(

In Beispiel 2.17 erscheint die geschachtelte Tabelle in der WHERE-Klausel der SELECT-Anweisung. Aus diesem Grund muss man dem System mitteilen, dass es sich um eineTabelle handelt. Dies wird bei Oracle mit dem Schlüsselwort TABLE erreicht, das vordem Namen der geschachtelten Tabelle geschrieben wird. (Ohne diese Umwandlungwürde der Wert a.verwandte als skalarer Wert (und nicht als geschachtelte Tabelle)betrachtet.)

Das folgende Beispiel zeigt die Änderung der geschachtelten Tabelle.

Beispiel 2.18

/�A�������)����)����&��G� ���6��7���@�+���8"������@� ��9�0�#1<%�&��������&� ����&'� ����9�2"�45�2�8"����&����:' �+��9�#01(

Beispiel 2.18 verwendet die UPDATE-Anweisung, um die Werte in der geschachteltenTabelle zu ändern. Für diesen Fall wird, genauso wie in Beispiel 2.17, das Schlüssel-wort TABLE verwendet, um dem System mitzuteilen, dass die Änderung diegeschachtelte und nicht die äußere Tabelle (arbeiter) betrifft.

����� ������������4 .

Instanzen, die in einer Objekttabelle erscheinen, werden Reiheninstanzen (row objects)genannt. Genauso werden Instanzen, die als Werte einer Spalte existieren, Spalten-instanzen (column objects) genannt. Damit ist z.B. die Instanz

�0�#1<>?=B�� �����2)� 52��2� �2%��#�%

in der SET-Klausel des Beispiels 2.8 eine Reiheninstanz, während

2)� 52��2� �2

eine Spalteninstanz der obigen Reiheninstanz darstellt.

Jede Reiheninstanz bei Oracle hat einen Identifikator (object identifier), mit dem dieseeindeutig identifiziert wird. Ein solcher Objektidentifikator kann verwendet werden,um einer Tabellenspalte eine ganze Instanz einer anderen (oder derselben) Tabellezuzuweisen. Dies wird mit Hilfe des REF-Datentyps durchgeführt. Damit ist REF einZeiger, der auf den Objektidentifikator einer Reiheninstanz zeigt.

Der REF-Datentyp findet in der Praxis u.a. Anwendung in folgenden Bereichen:

� für die Definition einer (rekursiven) Klasse-Komponentenklasse-Beziehung

� um (ineffiziente) Join-Operationen zu vermeiden.

Page 51: Java in Datenbanksystemen

�������������� ���������� �� ������ �

Die beiden folgenden Unterabschnitte beschreiben die obigen Anwendungen des REF-Datentyps.

�� ��.�� ��� /������/��0�������������+�#��

� Eine Klasse-Komponentenklasse-Beziehung ist eine spezielle Form allgemeinerBeziehungen zwischen zwei Klassen, wo eine Klasse (oder ihre Instanzen) alsDatentyp von Spalten einer anderen Klasse erscheinen. Beispiel 2.19 zeigt eineKlasse-Komponentenklasse-Beziehung.

Beispiel 2.19

�/�"�,:@ K�"���0#%���.� ���K�"���<$%��.'�K�"���#$%��!��4�5K!��)�H%

In Beispiel 2.19 ist eine Klasse namens BUCH dargestellt. Diese Klasse hat mehrereAttribute, von welchen die ersten drei mit Hilfe des Standarddatentyps CHARACTERdefiniert sind. Das letzte Attribut – Verlag – ist mit Hilfe einer anderen Klasse namensVERLAG definiert. Das heißt, dass eine (oder eventuell mehrere) Instanzen dieserKlasse benutzt werden, um das Attribut Verlag zu definieren. In diesem Fall wird dieKlasse VERLAG Komponentenklasse genannt, weil ihre Instanzen als Spaltendefini-tion einer anderen Klasse dienen.

Eine Klasse-Komponentenklasse-Beziehung kann auch rekursiv sein, falls Klasse undihre Komponentenklasse identisch sind. Beispiel 2.20 zeigt eine rekursive Klasse-Kom-ponentenklasse-Beziehung.

Beispiel 2.20

������������F.�:�������������+�4��"����<%�����������+ �4��"���0�$%�&'��.::�*. 5���6�F.�:�%���.���,-�%(����������)��F.�:��6�F.�:�(

Die Spalte voraussetzung der Klasse kurs_t in Beispiel 2.20 ist gleichzeitig eine Instanzderselben Klasse. (Man kann sich das so vorstellen, dass z.B. die Voraussetzung fürden Kurs »Datenbanken« die Instanz eines Kurses namens »Grundlagen der Informa-tik« ist.)

�����+�� ,�� 1���0����� �� 2�.� ,�� "�3�������0�

Die zweite praktische Anwendung des REF-Datentyps – die Ersetzung des Join-Opera-tors mit Hilfe des REF-Datentyps – werden wir mit Hilfe der modifizierten Tabellender Beispieldatenbank zeigen. Beispiel 2.21 zeigt dies.

Beispiel 2.21

�������������+��@�+������������������ ��+ ���� ����� ����$%����&'� ����� ����$%���@� ��� ����$%%(��������������';�F�����������

Page 52: Java in Datenbanksystemen

�� � �������������� ���������� ��������� ����������

������ ��� ���1%����� ����� ����$%��:� �'��� ����<%%(��������������@�+� ��������������� ��,-������ ���"���1%���.C5�@���"����<%���+ :����A�������@��+���6��+��@�+�������@���'���6���';�F�(

Beispiel 2.22

����������)���+��@�+��0��6��+��@�+���(����������)����';�F0��6���';�F�(����������)����@�+� 0��6���@�+� �(

In Beispiel 2.21 werden zuerst drei neue Typen (mitarbeiter_t, projekt_t undarbeiten_t) mit Hilfe der CREATE OBJECT TYPE-Anweisung erstellt. Auf der Basisdieser Objekttypen werden in Beispiel 2.22 die entsprechenden Tabellen (mitarbeiter1,projekt1, arbeiten1) erzeugt. Dabei haben die Tabellen mitarbeiter1 und projekt1 die-selbe Struktur (Tabellenschema), wie die Tabellen mitarbeiter und projekt in denTabellen 1.2 bzw. 1.3.

Die dritte Tabelle arbeiten1 unterscheidet sich von der in Kapitel 1 definierten Tabellearbeiten, weil sie zwei zusätzliche Spalten – arb_mit und arb_pro – enthält, die für dieReferenzierung je einer Reihe der Tabellen mitarbeiter1 und projekt1 (in dieser Rei-henfolge) dienen.

Folgendes Beispiel zeigt das Einfügen der Spaltenwerte in die Tabellen mitarbeiter1,projekt1 und arbeiten1.

Beispiel 2.23

+ :���+ '��+��@�+��0��� ����� �������&'� ������@� �%����������������������:�4���J�C�'���+��@�+��(+ :���+ '���';�F0���� ������ ������+�4%����������������������������������:�4���J�C�'����';�F(+ :���+ '���@�+� 0��� ����� ���.C5�@���+ :������@��+����@���'%����:�4������� ������� �����.C5�@������+ :�������C��%����C��%�������������������C�'����@�+� ������';�F0�����+��@�+��0���������������������G �������� ��9����� ��� ������� ��9������ �L

Die ersten beiden INSERT-Anweisungen verwenden die allgemein bekannte INSERT-Anweisung mit SELECT (siehe Beispiel 1.10), um Reihen der Tabelle mitarbeiter1 ein-zufügen. Die dritte INSERT-Anweisung fügt die Werte der Spalten arb_mit undarb_pro mit Hilfe von Referenzen ein, die auf einzelne Reihen der Tabellen projekt1und mitarbeiter1 zeigen.

Durch die Angabe dieser zusätzlichen Spalten in der Tabelle arbeiten1 ist es möglich,eine Verknüpfung der Tabellen mit dem Join-Operator zu ersetzen. Folgendes Beispielzeigt eine SELECT-Anweisung mit zwei Join-Operationen und die äquivalenteAbfrage mit Hilfe des REF-Typs.

Page 53: Java in Datenbanksystemen

�������������� ���������� �� *.���4 ��

Beispiel 2.24

Finden Sie die Mitarbeiteraufgabe, den Mitarbeiternamen und den Standort des Pro-jektes, in dem Mitarbeiter arbeiten, die nach dem 1.1.1988 in ihrem Projekt eingestelltwurden.

��)������@�+� ��.C5�@����+��@�+����� �������';�F��+�4���6��7��+��@�+������@�+� ����';�F���8"������+��@�+����� ��9���@�+� ��� �����-A���@�+� ���� ��9���';�F���� �����-A��+ :����I�20�0�0B==2(

Beispiel 2.25 ist dem Beispiel 2.24 identisch, verwendet aber die Spalten arb_mit undarb_pro, um die Join-Operationen in Beispiel 2.24 zu ersetzen.

Beispiel 2.25

��)�������.C5�@�������@��+��� ���������@���'��+�4����6��7���@�+� 0������8"�����+ :����I�20�0�0B==2(

Die Abfrage in Beispiel 2.24 verwendet die übliche Join-Operation, um die drei Tabel-len (mitarbeiter, arbeiten, projekt) miteinander zu verknüpfen. Die Abfrage in Bei-spiel 2.25 benutzt die zwei in Beispiel 2.21 definierten Spalten (arb_mit und arb_pro),um die Join-Operationen mit Hilfe des REF-Operators zu ersetzen. Dies ist möglich,weil die Spalte arb_mit der Tabelle arbeiten1 eine Instanz der Tabelle mitarbeiter1referenziert. Dasselbe gilt für die Spalte arb_pro, die eine Instanz der Tabelle projekt1referenziert.

��� �������������� �������������5�6��7

Objektorientierte Erweiterungen bei Informix haben ihren Ursprung in einem anderenobjektrelationalen System namens Illustra. Illustra wurde von der Firma Informix auf-gekauft, und die meisten objektorientierten Konzepte, die in Illustra implementiertwaren, wurden in den Datenbank-Server von Informix übernommen.

In diesem Buch werden wir folgende Informix-Erweiterungen in Bezug auf Objekt-orientierung beschreiben:

� benutzerdefinierte Datentypen

� Reihentypen

� Kollektionen

� Typ- und Tabellenhierarchien.

Die folgenden Abschnitte beschreiben diese objektorientierten Konzepte.

Page 54: Java in Datenbanksystemen

�� � �������������� ���������� ��������� ����������

����� �����"�3�6���������������

Der Datenbank-Server von Informix unterstützt folgende benutzerdefinierte Daten-typen:

� OPAQUE

� DISTINCT.

Im Allgemeinen kann man sagen, dass der OPAQUE- und DISTINCT-Datentyp einegrößere Flexibilität bei der Speicherung und Verwaltung der Datentypen ermöglichen.

��� �5678��������0

Der OPAQUE-Datentyp entspricht einem abstrakten Datentyp (ADT), d.h. einembenutzerdefinierten Typ beliebiger Komplexität. Mit der CREATE OPAQUE TYPE-Anweisung kann ein vom Benutzer definierter Basisdatentyp erstellt werden. Ein sol-cher Basisdatentyp kann danach genauso wie jeder andere vom Datenbanksystemunterstützte Datentyp verwendet werden.

Die Syntax der CREATE OPAQUE TYPE-Anweisung lautet:

����������M/��������� �����������,-���-�))�-H�"�9�F' :�N!��,��)���� 5�@��4+:��%(

typ_name kennzeichnet den Namen des zu erstellenden Typs. Die INTERNAL-LENGTH-Angabe legt die Anzahl von Bytes fest, die für die Darstellung eines Wertesdes definierten Typs notwendig sind. Die interne Länge kann entweder fest oder varia-bel sein. Falls es sich um eine feste Länge handelt, wird eine Konstante (konst) zuge-wiesen, während VARIABLE die unterschiedlichen Längen einzelner Instanzen(Werte) des neuen Datentyps kennzeichnet. angabe_liste ist eine optionale Liste mitdiversen unterschiedlichen Optionen.

Die Erstellung eines neuen Datentyps mit Hilfe der CREATE OPAQUE TYPE-Anwei-sung bedeutet nur den ersten Schritt bei seiner Definition. Nach der Erstellung desDatentyps müssen alle notwendigen Umwandlungsfunktionen, die das interne Formatdes Typs in das Benutzerformat (und umgekehrt) konvertieren, definiert werden. Erstnach der Definition dieser Funktionen kann ein abstrakter Datentyp sinnvoll in derPraxis verwendet werden.

Zusätzlich zu der Definition von Funktionen ist es auch notwendig, die Umwandlungdes neudefinierten Datentyps in einen anderen existierenden Datentyp zu gewährleis-ten. Diese Umwandlung wird mit der CREATE CAST-Anweisung durchgeführt.

Beispiel 2.26 zeigt die Erstellung eines abstrakten Datentyps mit den dazugehörigenFunktionen.

Page 55: Java in Datenbanksystemen

�������������� ���������� �� *.���4 ��

Beispiel 2.26

����������M/��������5@��,-���-�))�-H�"�9�0>���),H-7�-��9�1�%(�������6/-��,�-��5@�, ��)!���"��%���/�-���5@��O���-�)�-�7��PQ,-6��7,OA,�R�S� �R�5@��0�$R�5@��@4���5@�, �.%L)�-H/�H���(�������,7�),�,��������)!���"�������5@��������8,�"���5@�, %(�������6/-��,�-��5@��.���5@�%���/�-��)!���"���O���-�)�-�7��PQ,-6��7,OA,�R�S� �R�5@��0�$R�5@��@4���5@��.�.%L)�-H/�H���(��������������5@�����)!���"��������8,�"���5@��.%(

Beispiel 2.26 zeigt einen Ausschnitt aus der Skriptdatei, mit der die Erstellung eineskleinen Moduls (rgba) durchgeführt wird. Zuerst wird der neue abstrakte Datentyprgba mit Hilfe der CREATE OPAQUE TYPE-Anweisung erstellt. Die Funktion rgbaInist eine Umwandlungsfunktion (cast-Funktion), die das Benutzerformat in das interneFormat des neuen Datentyps umwandelt. Diese Funktion wird in der anschließendenCREATE CAST-Anweisung für die Erstellung einer impliziten Umwandlung zwischendem abstrakten Datentyp und dem Datentyp LVARCHAR verwendet. Die zweiteFunktion rgbaOut ist genauso eine Umwandlungsfunktion, die das interne Formatdes neuen Datentyps in das Benutzerformat umwandelt.

��� �*��*9:��������0

Der DISTINCT-Datentyp erlaubt die Definition eines neuen Typs auf der Basis einesexistierenden Datentyps. Mit der CREATE DISTINCT TYPE-Anweisung wird einneuer DISTINCT-Datentyp erstellt. Diese Anweisung hat folgende Syntax:

�������A,��,-���������� �������T.�44��

typ_name kennzeichnet den Namen des neuen Datentyps. quell_typ ist der Nameeines existierenden Datentyps, der als Quelle für den neuen Datentyp dient. quell_typkann jeder von Informix unterstützte Datentyp (Standard oder benutzerdefiniert) sein.

Beispiel 2.27 zeigt die Erstellung eines DISTINCT-Datentyps.

Beispiel 2.27

�������A,��,-���������4������,-��H��(

Page 56: Java in Datenbanksystemen

�$ � �������������� ���������� ��������� ����������

In Beispiel 2.27 wurde ein DISTINCT-Datentyp namens alter auf der Basis des Standard-datentyps INTEGER erstellt. Obwohl ein neuerstellter DISTINCT-Datentyp dieselbeDarstellung wie der darunterliegende Datentyp hat, können die beiden Datentypennicht direkt miteinander verglichen werden. Die einzige Alternative ist die Verwendungder Umwandlungsfunktion cast. Für den in Beispiel 2.27 erstellten Datentyp alter heißtdas, dass der Vergleich mit den Ganzzahlen direkt nicht möglich ist.

Jedesmal, wenn ein DISTINCT-Datentyp erstellt wird, werden implizit vom Informix-System zwei Umwandlungsfunktionen erstellt: Eine vom DISTINCT- zum Quelldaten-typ und umgekehrt. Alle für den Quelldatentyp definierten Funktionen und Umwand-lungsfunktionen können auf den entsprechenden DISTINCT-Datentyp angewendetwerden. Im Gegensatz dazu gelten alle neudefinierten Funktionen für den DISTINCT-Datentyp nicht für den entsprechenden Quelldatentyp.

����� ���4�0�����

Eine der wichtigsten Eigenschaften des relationalen Datenmodells ist, dass jeder ein-zelne Datenwert innerhalb einer Tabelle durch einen atomaren Wert dargestellt ist(siehe Eigenschaften des relationalen Datenmodels in Kapitel 1). Diese Eigenschaft giltnicht für objektrelationale Datenbanksysteme wie Oracle und Informix, weil dieseinnerhalb einer Spalte und einer Reihe mehrwertige Attribute bzw. ganze Tabellenspeichern können. Dementsprechend ist eine Tabelle bei Informix eine Sammlung vonSpalten, die entweder einen Standard- oder einen benutzerdefinierten Datentyp haben.

Ein Reihentyp bei Informix fasst mehrere Komponenten (Elemente) unterschiedlicherDatentypen zusammen. Ein Reihentyp kann sowohl einer Tabelle als auch einer einzi-gen Spalte zugewiesen werden. Falls ein Reihentyp einer Tabelle zugewiesen wird,definiert dieser die Schablone, nach der die Tabelle erstellt wird. Im Falle einer Spaltebedeutet eine solche Zuweisung, dass die Spalte aus mehreren unterschiedlichen Tei-len zusammengesetzt (nicht atomar) ist.

Jeder Reihentyp kann:

� benannt (named)

� namenlos (unnamed)

sein. Die Erstellung eines Reihentyps hängt davon ab, ob es sich um einen benanntenoder einen namenlosen Datentyp handelt.

�������

Der Reihentyp bei Informix entspricht dem Objekttyp bei Oracle.

Page 57: Java in Datenbanksystemen

�������������� ���������� �� *.���4 �&

Mit der CREATE ROW TYPE-Anweisung wird ein benannter Reihentyp erstellt. Einbenannter Reihentyp hat immer einen innerhalb der aktuellen Datenbank eindeutigenNamen. Bei der Erstellung eines benannten Reihentyps werden immer sein Name unddie Namen und Datentypen der zu ihm gehörenden Spalten festgelegt.

Die CREATE ROW-Anweisung hat folgende Syntax:

���������8�������� �������:��4�0��0��-���-/))��������:��4�������-���-/))������%�������/-A���:.�����(

typ_name ist der Name des neuerstellten benannten Datentyps. Der benannte Daten-typ hat eine oder mehrere Spalten. Jede Spalte wird mit Hilfe eines Standard- odereines benutzerdefinierten Datentyps definiert.

Die optionale Angabe UNDER ermöglicht die Definition des neuen Datentyps inner-halb einer Typhierarchie, wobei supertyp der Name eines existierenden Typs ist, dersich in der Hierarchie direkt über dem neu definierten Reihentyp befindet. (Zur Defini-tion der Typhierarchie und der Vererbung siehe Abschnitt 2.2.4.)

In Bezug auf eine Spalte kann ein benannter Reihentyp als Datentyp verwendet wer-den, falls die Spalte ein zusammengesetztes Attribut ist. Mit Hilfe des definiertenbenannten Reihentyps kann das System sowohl auf die ganze Spalte als auch auf ihreeinzelnen Komponenten zugreifen.

Beispiel 2.28 zeigt die Erstellung eines benannten Reihentyps.

Beispiel 2.28

���������8������ ��������� �� �����"����$%�-���-/))������&'� �����"����$%%(

Beispiel 2.29 zeigt die Erstellung eines weiteren Reihentyps, der später in diesem Kapi-tel verwendet wird.

Beispiel 2.29

���������8����������::�������:����"����<%�-���-/))������:��::���"����$%�-���-/))������ �.: ��,-��H���-���-/))%(

In den Beispielen 2.28 und 2.29 sind zwei benannte Reihentypen – name_t undadresse_t – erstellt worden. Diese beiden Reihentypen können jetzt wie jeder andereexistierende Datentyp einer Spalte zugewiesen werden (siehe nächstes Beispiel).

Page 58: Java in Datenbanksystemen

�( � �������������� ���������� ��������� ����������

Zwei benannte Reihentypen können nicht identisch sein, sogar wenn sie identischeStrukturen (Typschemata) aufweisen. Dies liegt daran, dass sie unterschiedlicheNamen haben. Im Unterschied dazu wird ein namenloser Reihentyp durch seineStruktur definiert. Damit sind zwei namenlose Reihentypen immer identisch, falls siedieselbe Struktur aufweisen. Mit Hilfe des CAST-Operators ist es trotzdem möglich,einen benannten Reihentyp in einen anderen benannten Reihentyp umzuwandeln.

Eine Tabelle kann typisiert oder nicht typisiert sein. Jede typisierte Tabelle wird mitHilfe eines benannten Reihentyps definiert. Eine nicht typisierte Tabelle ist diejenigeTabelle, die nicht auf einem entsprechenden Typ basiert. Die CREATE TABLE-Anwei-sung, mit der eine typisierte Tabelle erstellt wird, enthält die Angabe des benanntenReihentyps, der als Schablone für ihre Erzeugung verwendet wird.

Eine Spalte eines benannten Reihentyps darf bei Informix nur die NULL bzw. NOTNULL-Angabe als Integritätsregel enthalten. Alle anderen Integritätsregeln dürfenausschließlich für die entsprechende Tabelle angegeben werden.

Beispiel 2.30

���������8������C+������C+��� � ��,-��H���-���-/))�����C+��� � �����"����<%�-���-/))������::������::��%(����������)��C+�����6������C+��������,7����3���C+��� � �%%(

In Beispiel 2.30 wird zuerst ein benannter Reihentyp (firma_t) definiert. firma_t hat alsKomponente einen anderen Reihentyp: adresse_t (Beispiel 2.29), der für die Definitionder Spalte adresse verwendet wird. Anschließend wird eine entsprechende Tabelle(firma) erstellt. Diese typisierte Tabelle hat dasselbe Schema wie der entsprechendeReihentyp.

Ein namenloser Reihentyp kennzeichnet eine Gruppe von Feldern, die unterschied-liche Datentypen haben können. Im Unterschied zum benannten Reihentyp, der alsDatentyp einer Spalte oder als Schablone einer Tabelle verwendet wird, kann dernamenlose Reihentyp ausschließlich für die Definition einer Spalte verwendet werden.Ein namenloser Reihentyp kann mit Hilfe des ROW-Konstruktors erstellt werden.

Beispiel 2.31 zeigt die Verwendung eines namenlosen Reihentyps.

Beispiel 2.31

����������)��:.�� ��������+F�4� ��,-��H���-���-/))���,7����3�������� ������8� �� �����"����$%��&'� �����"����$%%%(

In Beispiel 2.31 enthält die Tabelle student u.a. eine Spalte name, die als namenloserReihentyp (mit den Feldern nachname und vorname) definiert ist.

Page 59: Java in Datenbanksystemen

�������������� ���������� �� *.���4 �)

Beim Einfügen der Werte eines Reihentyps kann sowohl ein benannter als auch einnamenloser Reihentyp verwendet werden. Der Bezug auf den darunterliegenden Rei-hentyp kann durch die Angabe des CAST-Operators »::« gemacht werden, dem dannder Reihentyp folgt. Beispiel 2.31 zeigt eine INSERT-Anweisung, die einen Reihentypeinfügt.

Beispiel 2.32

,-�����,-���C+����!�)/��������#<0==>��2�782����8��27D � � 2��23��4:���2��1%�KK����::��%(

Die INSERT-Anweisung in Beispiel 2.32 verwendet den CAST-Operator »::«, um denBezug zum Reihentyp adresse_t herzustellen.

Wie wir schon erläutert haben, können Spalten einer Tabelle mit Hilfe eines benanntenoder namenlosen Reihentyps definiert werden. Die Abfragen auf eine so definierteSpalte entsprechen der Abfrage auf eine Spalte, die mit Hilfe eines Standarddatentypsdefiniert ist. Beispiel 2.33 zeigt eine solche Abfrage.

Beispiel 2.33

��)����J����6��7�C+���(

Das Ergebnis ist:

C+��� � �������������#<0==>���������������������������������������������������������

C+��� � ��������������78����::����������������8�27D � � 2�23��4:��2�1%

Die Tabelle firma (Beispiel 2.32) enthält eine Reihe, die im Ergebnis dargestellt ist.

Mit der SELECT-Anweisung ist es auch möglich, einzelne Felder einer zusammenge-setzten Spalte abzufragen. In diesem Fall muss (wie bei Oracle) die Punktnotation(spalten_name.feld_name) verwendet werden. Beispiel 2.34 zeigt die Verwendung derPunktnotation.

Beispiel 2.34

��)��������::��:��������::��:��::�����6��7�C+��������8"����C+��� � ��9�#<0==>(

Das Ergebnis ist:

:�����������:��::�UUUUUUUUUUUUUUUUUUUUUUUU7D � � �������3��4:��

Page 60: Java in Datenbanksystemen

$- � �������������� ���������� ��������� ����������

Die Punktnotation kann auch auf eine Spalte, die mit Hilfe des namenlosen Reihentypsdefiniert ist, angewendet werden. Beispiel 2.35 zeigt dies.

Beispiel 2.35

��)����:.�� ����+F�4� ���:.�� � ���� �� �������6��7�:.�� ����8"�������+F�4� ��9�0�#1<(

Die SELECT-Anweisung in Beispiel 2.35 wählt eine einzige Reihe aus der Tabelle stu-dent (Beispiel 2.31) aus.

Das Ergebnis könnte sein:

���+F�4� ��������� �� �������������������������������

0�#1<��������������H�+��

Bei der Änderung einer Spalte, die als namenloser bzw. benannter Reihentyp definiertist, müssen alle Werte explizit angegeben werden.

Beispiel 2.36

/�A����C+���������������::��9�L��8�27D � � 2��2�':���2��0$%L����8"����C+��� � ��9�#<0==>(

Beispiel 2.36 zeigt die Änderung der Spalte adresse der Tabelle firma. Diese Spalte istmit Hilfe eines benannten Reihentyps definiert. Um diese Spalte zu ändern, muss dasSchlüsselwort ROW vor der Werteliste angegeben werden.

����� �����������

Ein Kollektionsdatentyp enthält mehrere Elemente, die alle denselben Datentyp haben.Als solcher kann er als Datentyp einer Spalte zugewiesen werden. Jeder Kollektions-datentyp hat zwei Merkmale: den Typkonstruktor und den Datentyp der Elemente.

�������

Die Änderung einer Reihentypspalte kann mit der interaktiven front-end-Kompo-nente von Informix nur so durchgeführt werden, dass die Werte aller Felder des Rei-hentyps geändert werden. Falls einzelne Werte modifiziert (eingefügt, geändertbzw. gelöscht) werden sollen, muss eine Programmierschnittstelle (SPL bzw. ESQL)verwendet werden.

Page 61: Java in Datenbanksystemen

�������������� ���������� �� *.���4 $

Zu den Kollektionen gehören generell:

� Menge (set)

� Multimenge (multiset bzw. bag)

� Liste (list)

� Vektor (array)

� geschachtelte Tabellen (nested tables).

Ein Mengenkonstruktor erzeugt aus mehreren Elementen eines zugrunde liegendenTyps einen neuen Typ. Die Elemente einer Menge haben keine Ordnung. Genauso ent-hält eine Menge keines der Elemente mehrfach. Ein Multimengenkonstruktor ent-spricht einem Mengenkonstruktor bis auf eine Ausnahme: die mehrfache Erscheinungeinzelner Elemente ist erlaubt.

Im Unterschied zu den Kollektionen Menge und Multimenge hat eine Liste geordneteElemente und kann ein Element mehrfach enthalten. Damit existiert bei einer Liste daserste Element, das zweite usw., während bei Mengen und Multimengen solche Klassi-fizierung der Elemente nicht möglich ist.

Ein Vektor (array) ist, bis auf einen Unterschied, identisch mit dem KollektionstypListe. Im Unterschied zu Liste hat Vektor eine konstante Anzahl von Elementen. Einegeschachtelte Tabelle ist diejenige Tabelle, die in einer anderen Tabelle anstelle einesDatenwertes erscheint. (Die Unterstützung der geschachtelten Tabellen verletzt dieerste Normalform des relationalen Datenmodells.)

Der Typkonstruktor eines Kollektionsdatentyps bei Informix kann:

� Menge (SET)

� Multimenge (MULTISET)

� Liste (LIST)

sein.

Eine Menge wird bei Informix mit Hilfe des Schlüsselwortes SET erstellt. Beispiel 2.37zeigt zuerst die Erstellung eines Typs und danach die Erstellung einer Tabelle mit einerSpalte, die vom Typ SET ist.

�������

Kollektionen haben gewisse Ähnlichkeiten mit den schon beschrieben Reihentypen.Im Unterschied zu den Reihentypen, die generell mehrere Elemente verschiedenerDatentypen haben, enthalten Kollektionen immer Elemente desselben Datentyps.

Page 62: Java in Datenbanksystemen

$� � �������������� ���������� ��������� ����������

Beispiel 2.37

���������8������� 5�:�44�������� 5� ��,-��H���-���-/))������ 5� �����"����$%�-���-/))������ 5�&'� ���������"����$%�-���-/))%%(����������)��� 5�:�44����6������� 5�:�44�����������,7����3���� 5� �%%(

In Beispiel 2.37 ist ein benannter Reihentyp angestellter_t erstellt worden, dessenSpalte ang_vorname mit Hilfe des SET-Typs definiert ist. Das ist auch nahe liegend,weil alle Vornamen eines Mitarbeiters verschieden sein sollen.

Der Typkonstruktor SET kann, genauso wie alle anderen Typkonstruktoren, für dieDefinition einer nicht typisierten Tabelle verwendet werden.

Beispiel 2.38

����������)��F' *�� ��������F' *�� � �����"���#$%�-���-/))���,7����3�����������:� �'��������"����$%�-���-/))%%(

Eine Multimenge ist eine nichtgeordnete Sammlung von Elementen desselben Daten-typs. (Jedes Element einer Multimenge kann mehrfach vorkommen.) Sie wird mit Hilfedes Schlüsselwortes MULTISET definiert. Beispiel 2.39 zeigt die Verwendung vonMULTISET.

Beispiel 2.39

���������8������4� ���������4� ���� ��,-��H���-���-/))������ ���� ���������������::������::��������+�4�7/)�,�����"���=%�-���-/))%%(����������)��4� �����6������4� ��������,7����3���4� ���� �%%(

In Beispiel 2.39 wurde der Typ lehrer_t erstellt, dessen erste beide Spalten mit Hilfe derschon existierenden benannten Reihentypen name_t und adresse_t (Beispiele 2.28 und2.29) und dessen letzte Spalte mit Hilfe des Schlüsselwortes MULTISET definiert sind.Die Spalte titel ist als eine Multimenge definiert, weil ein Lehrer mehrere, eventuellsich wiederholende Titel (Prof. Dr. usw.) haben kann.

Eine Liste ist eine geordnete Sammlung von Elementen desselben Datentyps, die auchmehrfach vorkommen können. Sie wird mit Hilfe des Schlüsselwortes LIST erstellt.Beispiel 2.40 zeigt die Verwendung dieses Kollektionstyps.

Page 63: Java in Datenbanksystemen

�������������� ���������� �� *.���4 $�

Beispiel 2.40

���������8������&@������� .�����,-��H���-���-/))������ �����"����$%�-���-/))������.�:�*���'��' ��),���7�-���-���-/))%%(����������)��&@��6������&@�����,7����3���� .����%%(

In Beispiel 2.40 wird ein benannter Reihentyp erstellt, der u.a. die Spalteumsatz_pro_monat enthält. Diese Spalte beinhaltet Umsätze jedes einzelnen Monats(Januar, Februar usw.) und muss deswegen geordnet, d.h. als Liste definiert werden.

Komplexe Datentypen können geschachtelt sein. Es ist z.B. möglich, einen Kollektions-datentyp zu definieren, dessen Werte einen Reihentyp oder wieder einen Kollektions-datentyp enthalten. Genauso ist es möglich, dass ein Reihentyp einen oder mehrereWerte vom Typ SET, MULTISET oder LIST enthält.

Beispiel 2.41 zeigt die Schachtelung von Typkonstruktoren.

Beispiel 2.41

���������8�������+�4'�� ���������+F�4� ��,-��H���-���-/))����� ���� ��������� '� �4+:��),�����8�C�� ��"����$%�� '��,-��H��%�-���-/))%%(����������)���+�4'�� ���6�������+�4'�� ������,7����3������+F�4� �%%(

Der Typ diplomand_t in Beispiel 2.41 beinhaltet u.a. die Spalte noten_liste, die alsListe aller Noten in der folgenden Form gespeichert wird:

7� ���+F������0��+:+F�������#��'5����+��. 5���

Das folgende Beispiel zeigt, genauso wie das vorherige Beispiel, die Schachtelung vonTypkonstruktoren.

Beispiel 2.42

���������8������@.� ������+:@ ��"���0#%�-���-/))�������.'�� �4+:��),������8� �����"����$%������&'� ��� ������"����$%�-���-/))%%�-���-/))%������@.� �+�4�"���<$%%(����������)��@.� ��6������@.� �����,7����3����+:@ %%(

Beispiel 2.42 beinhaltet u.a. die Spalte autoren_liste, die als Liste aller Autoren darge-stellt ist. Jeder Autor ist mit Hilfe eines namenlosen Reihentyps definiert, der auch dasFeld vornamen vom Typ SET enthält.

Page 64: Java in Datenbanksystemen

$� � �������������� ���������� ��������� ����������

Beim Einfügen der Werte einer Spalte vom Typ SET, MULTISET und LIST müssen fol-gende syntaktische Regeln beachtet werden:

� vor der Werteliste muss der entsprechende Konstruktor (SET, MULTISET oderLIST) stehen.

� das Schlüsselwort SET (MULTISET bzw. LIST) muss, gemeinsam mit der Werteliste,innerhalb von Anführungszeichen geschrieben werden.

Beispiel 2.43 zeigt das Einfügen einer Reihe in die Tabelle mit der MULTISET-Spalte.

Beispiel 2.43

,-�����,-���4� ��������!�)/����0�#1<��������8�2����:2��2� �2%�KK ������������8�2/4�2��23��4:���2��01%�KK����::��������L7/)�,����2��'C��2��2A���2��2A���2�L%(

In Beispiel 2.43 wird die typisierte Tabelle lehrer (Beispiel 2.39) verwendet. DieINSERT-Anweisung verwendet das Schlüsselwort MULTISET, um der Spalte titelWerte zuzuweisen.

Beim Einfügen der Werte ist es auch möglich, eine leere Menge bzw. Multimenge anzu-geben. Eine leere Menge enthält keine Elemente. Folgendes Beispiel zeigt das Einfügeneiner leeren Multimenge.

Beispiel 2.44

,-�����,-���4� �����!�)/�����#1<>���8�2)'��2��28'4C5� 52%�KK ���������8�27D � � 2��28+ ���F:�2��0B%�KK����::���L7/)�,�����L%(

Abfragen auf eine Spalte, die mit Hilfe eines Kollektionsdatentyps definiert ist, liefernalle Elemente einer Menge, Multimenge oder Liste. Beispiel 2.45 zeigt eine Abfrage aufeine Spalte, die vom Typ SET ist.

Beispiel 2.45

��)����� 5� ���� 5�&'� ������6��7�� 5�:�44��(

Das Ergebnis könnte folgendermaßen aussehen:

� 5� ������������===� 5�&'� ����������������2� �2��27��+�2��2����2�� 5� ������������BBB� 5�&'� ����������������2����2��234�.:2�

Die Tabelle angestellter (Beispiel 2.37) enthält eine Spalte ang_vorname, die vom TypSET ist. Wie aus dem Ergebnis des Beispiels 2.45 ersichtlich, enthält die Ausgabe einer

Page 65: Java in Datenbanksystemen

�������������� ���������� �� *.���4 $�

Spalte, die mit Hilfe eines Kollektionsdatentyps definiert ist, immer den Namen desKonstruktors (SET, MULTISET bzw. LIST).

Die IN-Angabe kann ebenfalls verwendet werden, um festzustellen, ob eine Spaltevom Typ SET, MULTISET oder LIST einen gewissen Wert enthält.

Beispiel 2.46

��)����� 5� ���� 5� ������ 5�&'� ������6��7�� 5�:�44�����8"����2����2�,-�� 5�&'� ���(

Das Ergebnis könnte folgendermaßen aussehen:

� 5� �����������===� 5�&'� ������������2� �2��27��+�2��2����2�

Mit der SELECT-Anweisung in Beispiel 2.46 werden diejenigen Reihen der Tabelleangestellter ausgesucht, die den Vornamen Petra in der SET-Spalte ang_vorname ent-halten. Obwohl die IN-Angabe die Einschränkung der Suche auf einen einzigen Wertder Spalte vom Typ SET, MULTISET oder LIST ermöglicht, enthält die Ausgabe immeralle Werte des entsprechenden Kollektionstyps.

Der Datenbank-Server von Informix unterstützt die Funktion cardinality, mit der dieAnzahl der Elemente eines Kollektionsdatentyps berechnet werden kann. Beispiel 2.47zeigt die Anwendung der cardinality-Funktion.

Beispiel 2.47

��)����� 5� ������A,-�),���� 5�&'� ���%�� *� 4�&'� ��� ������6��7�� 5�:�44��(

Die SELECT-Anweisung in Beispiel 2.47 gibt die Personalnummer jedes Angestelltenund die Anzahl seiner Vornamen.

Bei der Änderung einer Spalte, die mit Hilfe eines Kollektionsdatentyps definiertwurde, gelten folgende Regeln:

� alle Elemente müssen explizit angegeben werden,

� alle Elemente müssen, gemeinsam mit dem Schlüsselwort SET (MULTISET bzw.LIST), innerhalb von Anführungszeichen geschrieben werden.

Beispiel 2.48

/�A����4� �����������+�4�9�L7/)�,����2��'C��2��2��'C2��2A��2��2A��2�L����8"����4� ���� ��9��#1<>(

Page 66: Java in Datenbanksystemen

$$ � �������������� ���������� ��������� ����������

In Beispiel 2.48 werden alle Titel (alte und neue) des Lehrers mit der Nummer 23456innerhalb der SET-Klausel angegeben. Dies ist unbedingt notwendig, weil das Einfügeneinzelner Elemente mit den front-end-Komponenten von Informix nicht möglich ist.

���� 8������3�8�������0���0��

Der Datenbank-Server von Informix unterstützt noch ein weiteres objektorientiertesKonzept, nämlich Typ- bzw. Tabellenhierarchien. Im Allgemeinen kennzeichnet eineObjekthierarchie eine Sammlung von Objekten, in der ein Objekt entweder eine Wur-zel, einen Knoten oder ein Blatt eines Baums darstellt. Dementsprechend kennzeichnetdie Typhierarchie eine Sammlung von Datentypen, wobei jeder Datentyp in der exis-tierenden Hierarchie entweder eine Wurzel oder ein Knoten oder ein Blatt ist. Bei einerTyphierarchie wird ein Typ T1 der Supertyp von T2 genannt, falls T2 in der Hierarchiedirekt oder indirekt unter dem Typ T1 liegt. Genauso wird T2 der Subtyp von T1genannt.

%�������

Alle Hierarchien (Objekt-, Typ- und Tabellenhierarchien) unterstützen die Vererbung.Dieser Begriff bedeutet, dass alle Eigenschaften eines Objektes (Typs) wie Attributebzw. dazugehörende Funktionen von allen seinen Unterobjekten (Subtypen) automa-tisch geerbt werden.

Die Vererbung kann einfach oder mehrfach sein. Eine einfache Vererbung kennzeich-net die Eigenschaft einer Hierarchie, wo jeder Typ maximal einen Supertyp hat. Dem-entsprechend hat bei der mehrfachen Vererbung mindestens ein Typ der Hierarchiezwei oder mehrere Supertypen. (Informix unterstützt in der aktuellen Version die ein-fache Vererbung.)

��0#�����#�

Typhierarchien können nur mit benannten Reihentypen erstellt werden. Beispiel 2.49zeigt die Erstellung einer Typhierarchie für die Typen person_t, kurs_teiln_t, dozent_tund prof_t (siehe Abbildung 2.1).

Beispiel 2.49

���������8���������:' ������ ���� ��������������::������::���������4�C' � ��,-��H��%(���������8������F.�:��+4 ������C+����C+����������C. F+' ��"����$%%�����/-A������:' �(���������8�������'*� �

Page 67: Java in Datenbanksystemen

�������������� ���������� �� *.���4 $&

������ *� 4�:. �� �,-��H��%�����/-A������:' �(���������8��������'C������+�4�7/)�,�����"���=%�-���-/))%%����/-A����'*� �(

Wie aus Beispiel 2.49 ersichtlich, muss die Definition jedes Subtyps die AngabeUNDER enthalten. Die Definition eines Supertyps muss immer vor der Definition sei-ner Subtypen erfolgen. Abbildung 2.1 zeigt die in Beispiel 2.49 definierte Typhierar-chie.

Durch die Vererbung enthält jeder Subtyp zusätzlich zu seinen eigenen Eigenschaften(Spalten und Routinen) auch die Eigenschaften aller seiner Supertypen. Damit enthältz.B. der Typ prof_t insgesamt fünf Attribute (Spalten): name, adresse, telefon_nr,anzahl_stunden und titel.

�������#�����#�

Eine Tabellenhierarchie kann nur erstellt werden, falls die entsprechende Typhierar-chie existiert. Weil auf der anderen Seite eine Typhierarchie für sich wenig Sinn macht,empfiehlt es sich, die Typ- und die entsprechende Tabellenhierarchie gleich nacheinan-der zu erstellen.

Jede Subtabelle muss genauso wie der entsprechende Subtyp die Angabe UNDER ent-halten. Beispiel 2.50 erstellt die entsprechende Tabellenhierarchie für die in Beispiel2.49 definierte Typhierarchie.

Beispiel 2.50

����������)�����:' ��6���������:' �(����������)��F.�:��+4 ��6������F.�:��+4 ��/-A������:' (����������)���'*� ��6�������'*� ��/-A������:' (����������)����'C��6��������'C��/-A����'*� (

6���,�� �� ! ��0#�����#� ,�� ���0��� ���)

Page 68: Java in Datenbanksystemen

$( � �������������� ���������� ��������� ����������

In einer Tabellenhierarchie bei Informix erbt eine Subtabelle folgende Eigenschaftenaller ihrer Supertabellen:

� alle Spalten

� alle definierten Integritätsregeln

� alle definierten Zugriffsmethoden

� Speicherangaben

� Trigger

� Indizes.

Beim Einfügen einer Reihe in eine Tabelle, die zu einer Tabellenhierarchie gehört, gibtes keine Besonderheiten. Die Reihe wird in jene Tabelle eingefügt, die in der INSERT-Anweisung angegeben ist. Beispiel 2.51 zeigt das Einfügen der Reihen in der in Bei-spiel 2.50 definierten Tabellenhierarchie.

Beispiel 2.51

,-�����,-������:' �� ���������::����4�C' � �%�����!�)/����L��8�23.�*2��2).�G+52%L������L��8�2�':� �+�2��2�':��2��01%L������<$=#�%(,-�����,-���F.�:��+4 �� ���������::����4�C' � ���C+�����C. F+' %�����!�)/����L��8�2)� 52��2����2%L������L��8�2�':� �+�2��2�':��2��01%V�0�#1<��������8�0�#1<��23� ��2����8�2�':� �+�2��23� ��:��2�?%KK���������::���%KKC+�����2��';�F4�+��2%(,-�����,-����'*� � ���������::����4�C' � ��� *� 4�:. �� %�����!�)/����L��8�27D44��2��2�44�2%L������L��8�2�':� �+�2��2�':��2��01%L������<#<<=��#<%(,-�����,-�����'C�� ���������::����4�C' � ���� *� 4�:. �� ��+�4%�����!�)/����L��8�27+44��2��2� �2%L������L��8�2�':� �+�2��2�':��2��01%L������<<#�0��0=������L7/)�,����2��'C�2�2A��2�L%(

Eine Abfrage auf eine Supertabelle kann entweder auf die Supertabelle und alle ihreSubtabellen angewendet oder nur auf die Supertabelle eingeschränkt werden. Fol-gende Beispiele zeigen die beiden Alternativen.

�������

Die erste Eigenschaft (Spalten) stellt eine Struktureigenschaft dar, während alleanderen in Bezug auf das Verhalten der Tabelle stehen.

Page 69: Java in Datenbanksystemen

�������������� ���������� �� ��� $)

Beispiel 2.52

��)���� ������4�C' � ������6��7����:' (

Die SELECT-Anweisung in Beispiel 2.52 wählt alle Reihen aus der Tabelle person (Bei-spiel 2.50) und aus allen ihren Subtabellen aus. Die Abfrage liefert keine Spalten, diespezifisch für einzelne Subtabellen sind.

Das Ergebnis einer Abfrage kann mit Hilfe der ONLY-Angabe auf Reihen der Super-tabelle eingeschränkt werden.

Beispiel 2.53

��)���� ������4�C' � �����6��7��-)�����:' %(

Die Änderung einer Spalte einer Tabelle, die sich innerhalb einer Tabellenhierarchiebefindet, beeinflusst Reihen dieser Tabelle und Reihen aller ihrer Subtabellen. Beispiel2.54 zeigt das.

Beispiel 2.54

/�A�������:' ������������::��9�L��8�2/4�2��2)� �:���2��0%L����8"��������::��9�L��8�2�':� �+�2��2�':���2��01%L(

In Beispiel 2.54 werden Reihen der Tabelle person und aller ihrer Subtabellen, in denendie Bedingung erfüllt ist, geändert. Die SET-Klausel der UPDATE-Angabe darf aus-schließlich die Spalten, die sich in der genannten Supertabelle befinden, enthalten.

Die Änderung einer Spalte kann mit Hilfe der ONLY-Angabe nur auf die Reihen dergenannten Supertabelle eingeschränkt werden.

Beispiel 2.55

/�A�����-)�����:' %������������::��9���8�2/4�2��2)� �:���2��0%KK����::������8"��������::��9���8�2�':� �+�2��2�':���2��01%KK����::��(

Mit der UPDATE-Anweisung in Beispiel 2.55 werden nur Reihen der Tabelle person,die die Bedingung erfüllen, geändert.

��� �������������� ����������������

Die Firma IBM hat im Vergleich zu Informix und Oracle relativ spät angefangen, dieobjektorientierten Erweiterungen in ihren Datenbank-Server zu implementieren. Erstim Jahre 2000 sind in Version 7.1 einige Erweiterungen implementiert worden. Zu die-sen gehören:

Page 70: Java in Datenbanksystemen

&- � �������������� ���������� ��������� ����������

� benutzerdefinierte Datentypen

� der REF-Operator

� Typ- und Tabellenhierarchien.

DB2 unterstützt zwei benutzerdefinierte Datentypen:

� DISTINCT-Datentyp

� Objekttyp.

Der DISTINCT-Datentyp entspricht genau dem gleichnamigen Datentyp bei Informix(siehe die Beschreibung des DISTINCT-Datentyps in Abschnitt 2.2.). Der Objekttypentspricht dem Objekttyp bei Oracle, hat aber eine etwas andere Syntax. Beispiel 2.56zeigt die Erstellung des Objekttyps name_t (Beispiel 2.1) mit DB2.

Beispiel 2.56

������������-������������� �� ����!���"���#$%��&'� ����!���"����$%�7�A��A����M)

Der REF-Datentyp hat dieselbe Syntax und Bedeutung wie der gleichnamige Datentypbei Oracle, während die Tabellenhierarchien den Tabellenhierarchien bei Informix ent-sprechen mit wenig geänderter Syntax. Beispiel 2.57 zeigt die Erstellung der Typhierar-chie entsprechend dem Beispiel 2.49, während Beispiel 2.58 die Erstellung derTabellenhierarchie mit DB2 illustriert.

Beispiel 2.57

���������������:' ��������� ���� ��������������::������::���������4�C' � ��,-��H��%(�7�A��A����M)������������F.�:��+4 ��/-A������:' ��������C+����C+����������C. F+' ��"����$%%������������������'*� ��/-A������:' ��������� *� 4�:. �� �,-��H��%�������������������'C��/-A������:' ��������+�4�7/)�,�����"���=%�-���-/))%%

Beispiel 2.58

����������)�����:' ��6����:' �����������)��F.�:��+4 ��6�F.�:��+4 ��/-A������:' ����������)���'*� ��6��'*� ��/-A������:' ����������)����'C��6���'C��/-A����'*�

Page 71: Java in Datenbanksystemen

;������.����� &

Die ausführliche Erläuterung der oben genannten objektorientierten Erweiterungen(sowie manche andere Erweiterungen, die nicht aufgelistet sind), liegt außerhalb derThemen dieses Buches, weil zum Zeitpunkt des Schreibens die JDBC 2.0-Erweiterun-gen in DB2 noch nicht implementiert sind. (Die Firma IBM arbeitet gerade daran.)

�� 9�������6������

In diesem Kapitel haben wir objektorientierte Erweiterungen dreier Datenbankherstel-ler: Oracle, Informix und IBM DB2 beschrieben. Zusammenfassend kann man sagen,dass jede Firma z. T. verschiedene Erweiterungen implementiert hat und, falls einKonzept in mehreren Datenbank-Servern existiert, seine Syntax bei unterschiedlichenHerstellern verschieden ist. Von allen drei Herstellern hat Informix die meisten objekt-orientierten Erweiterungen implementiert, während die beiden anderen Hersteller(Oracle und IBM) standardisierte Erweiterungen (d.h. diejenigen Erweiterungen, die imSQL99-Standard beschrieben sind), enthalten.

Das nächste Kapitel ist das letzte Kapitel des Einführungsteils. Es beschreibt die wichtig-sten Teile der Java-Sprache, die wir im weiteren Verlauf des Buches benötigen werden.

Page 72: Java in Datenbanksystemen
Page 73: Java in Datenbanksystemen

� ����������� ������������������

Java ist eine objektorientierte Sprache, die von der Firma Sun Microsystems entworfenund implementiert wurde. Diese Sprache hat in den letzten Jahren an Bedeutunggewonnen, weil sie besonders für Internet-Anwendungen geeignet ist. Aus diesemGrund ist Java für die meisten Informatiker (und Nichtinformatiker) bekannt als Spra-che, mit der Applets implementiert werden können. (Applets sind Mini-Anwendun-gen, die innerhalb einer Web-Seite ablaufen. Sie ermöglichen die Ausführung vonAufgaben auf einem Web-Browser und die Kommunikation mit den Benutzern, ohnedass die Ressourcen des Web-Servers nach dem Runterladen der notwendigen Infor-mation noch einmal in Anspruch genommen werden müssen.)

Die wichtigste Eigenschaft von Java ist ihre Rechnerunabhängigkeit, was die Ausfüh-rung von Code auf entfernten Rechnern ermöglicht. Diese Eigenschaft ist die Grund-lage für die Verwendung dieser Sprache im Internet bzw. in jeder verteiltenNetzwerkumgebung.

Obwohl Java meistens für verteilte Umgebungen verwendet wird, ist sie eine Pro-grammiersprache, die für die Implementierung aller möglichen Anwendungenbenutzt werden kann. Bei Java handelt sich um eine objektorientierte Sprache, die alsNachfolgesprache von C und C++ bekannt ist, gleichzeitig aber gewisse Mankos dieserSprachen behebt.

��� ����������

Java-Programme werden aus einer oder mehreren Klassen gebildet. Jede definierteKlasse ermöglicht die Erstellung einzelner Instanzen dieser Klasse. (Man kann sicheine Java-Klasse als eine Fabrik vorstellen, die als Produkte Instanzen dieser Klasseerzeugt.)

Wie jede objektorientierte Sprache enthält eine Java-Klasse zwei Arten von Elementen:Attribute, die bei Java Felder (fields) genannt werden und Methoden (methods). MitHilfe eines kleinen Programms werden wir zeigen, wie eine Klasse in Java definiertwird.

Page 74: Java in Datenbanksystemen

�� ������������ ������������������� ���

Beispiel 3.1

��������������

������������� � ��������������� ��������������

�������������� ���� ���� �������������

������������������������������������������������

�����������

In Beispiel 3.1 wurde eine Klasse namens Hallo definiert. (Java unterscheidet zwischenGroß- und Kleinbuchstaben. Das ist ein wichtiger Unterschied zu der SQL-Sprache, diesolche Unterscheidung nicht macht.) Alle Elemente einer Klasse werden innerhalb einesgeschweiften Klammernpaares angegeben. Die Klasse Hallo enthält eine Methodenamens main() und keine Felder. Diese Methode hat einen Vektor namens args als einzi-gen Parameter, der vom Typ String ist. (Der Parameter der main()-Methode bei Java hatdieselbe syntaktische Form und Bedeutung wie der Parameter des main-Programmsbei der Sprache C. Dementsprechend wird auch die main-Methode mit Hilfe des Daten-typs void deklariert, was bedeutet, dass kein Rückgabewert geliefert wird.)

Die Methode main enthält eine einzige Anweisung:

���� ���� ���� ���������� ��

die die Methode println() aufruft. System ist eine (vordefinierte) Java-Klasse, die dasFeld out beinhaltet. Das Feld out ist eine Instanz der Klasse Printstream, und dieserTyp enthält unter anderen Mehoden auch die Methode println(). (Wie aus der Defini-tion der obigen Anweisung ersichtlich, wird eine Methode mit Hilfe der Punktnotationaufgerufen.) Die Methode println enthält eine alphanumerische Zeichenkette als Para-meter, die am Bildschirm ausgegeben wird.

Nachdem wir ein einfaches Java-Beispiel gezeigt und erläutert haben, werden wirzuerst nichtobjektorientierte Sprachelemente wie Variablen und Schleifenanweisungender Java- Sprache erörtern.

��� ��������������������� ������!���

Java unterscheidet zwischen den Standarddatentypen, die auch primitive Datentypengenannt werden und Instanzen einer Klasse. Der Unterschied zwischen den primitivenTypen und Instanzen einer Klasse ist, dass die primitiven Typen in der Sprache einge-baut sind, während Instanzen von Programmierern definiert sind.

�������

Ein Java-Programm, das die main()-Methode enthält, läuft unabhängig von jedemBrowser. Zur Ablaufzeit ruft die JVM (Java Virtual Machine) die main()-Methodeauf, und gibt einen Fehler aus, falls sie nicht vorhanden ist.

Page 75: Java in Datenbanksystemen

������������������������������� �� �!

Die primitiven Datentypen sind:

� boolean (entweder richtig oder falsch)

� char (Unicode-Zeichen der Länge 16 Bit)

� byte (Ganzzahlen der Länge 8 Bit)

� short (Ganzzahlen der Länge16 Bit)

� int (Ganzzahlen der Länge 32 Bit)

� float (Gleitkommazahlen der Länge 32 Bit)

� double (Gleitkommazahlen der Länge 64 Bit).

Obwohl die primitiven Datentypen bei Java große Ähnlichkeiten mit den Datentypenbei C und C++ aufweisen, haben sie einen wichtigen Unterschied: Alle primitivenTypen haben eine invariante (feste) Länge, die nicht von den Eigenschaften der Hard-ware, auf dem das Programm abläuft, abhängig sind. Dies ist auch notwendig, damitProgramme (von einem Rechner zu einem anderen) portierbar sind.

Beispiel 3.2 zeigt einige Beispiele von Java-Variablen und Konstanten.

Beispiel 3.2

�� ����!�"�!��#$�%�&���� �������'�� ()������������*��������$#

���!�++���#$����!�"����!�+�!�$#

���!�+"�!��##����!�"����!�+�!

� � ���,�������������"��-�!.!/�

� � ���,�������������"�!�

Die erste Zeile des Beispiels 3.2 zeigt die Deklaration und Wertzuweisung einer Java-Variablen. Die zweite und dritte Zeile zeigen zusätzlich die verkürzten Schreibweisen,die verwendet werden können, um einer Variablen einen Wert dazu zu addieren.

Beispiel 3.2 zeigt zusätzlich, welche Kommentare die Sprache Java unterstützt. Bei Javagibt es drei verschiedene Arten von Kommentaren. Neben den Zeichenpaaren »/*«und »*/«, die in Beispiel 3.2 verwendet wurden und den Kommentaren bei der Spra-che C entsprechen, unterstützt Java auch das Zeichenpaar »//«: Jeder Text, der demKommentar »//« folgt, wird bis zum Zeilenende vom Übersetzer außer Acht gelassen.

Der dritte Kommentartyp stellt den Dokumentationskommentar (doc comment) dar.Dokumentationskommentare erscheinen zwischen den Zeichenfolgen »/**« und »*/«.Sie werden meistens für die Beschreibung der Deklarationen verwendet. Das Java-Werkzeug namens javadoc extrahiert den Text zwischen den beiden Zeichenfolgenund generiert daraus ein HTML-Dokument.

Page 76: Java in Datenbanksystemen

�" ������������ ������������������� ���

Konstanten in der Java-Sprache sind immer benannt. Benannte Konstanten haben zweiVorteile im Vergleich zu den unbenannten:

1. durch die Benennung einer Konstante wird diese (durch ihren Namen) dokumen-tiert.

2. falls eine benannte Konstante geändert werden muss, erfolgt diese Änderung aneiner einzigen Stelle (im Unterschied zu den unbenannten, die überall geändertwerden müssen, wo sie vorkommen). Benannte Konstanten werden in Java alsVariablen mit den Eigenschaften static und final deklariert.

Die beiden letzten Reihen des Beispiels 3.2 zeigen zusätzlich zu der Definition zweierbenannter Konstanten auch eine weitere Eigenschaft von Java, nämlich die Unterstüt-zung von Unicode-Zeichen, wie z.B. � (Pi).

Unicode ist ein 16-Bit Zeichensatz, der vom Unicode-Konsortium entwickelt und ver-trieben wird. Unicode umfasst fast alle Zeichen, die heutzutage weltweit für Rechnerverwendet werden. Der Grund liegt darin, dass ein 16-Bit-Zeichensatz mehr als 64.000Zeichen aufnehmen kann.

Im Gegensatz zu den ersten Zeichensätzen, die nur eine begrenzte Anzahl von Zeichenaufnehmen konnten, stellt Unicode eine einheitliche Methode für die Aufnahme unter-schiedlichster Zeichen dar. Das bedeutet, dass mit Unicode die Darstellung von Zei-chen vieler Alphabete gleichzeitig in einem Dokument möglich ist.

����� ��"������#$��!�%��� ��������

Ein Vektor (array) ist eine Kollektion mehrerer Elemente, die alle denselben Datentyphaben. Der Datentyp des Vektorelementes kann ein primitiver oder komplexer Typsein. (Für die ausführliche Beschreibung von Vektoren siehe den Abschnitt »Kollek-tionen« in Kapitel 2.)

Um einen Vektor zu definieren, wird der sogenannte Indexoperator »[]« verwendet.Beispiel 3.3 zeigt die Definition und die Initialisierung einiger Vektoren.

Beispiel 3.3

�� �����& ��!�

�� �����& ��0�"��!101-1.12��

�� ����3���

�3���"���& ��0�

�� ������� ��4��"������##�5�� ��������������������� �����6��

������!1�01�-1�1

�����.1�21�/�1

����������������������

�� ����������������"���)��� �0���-���.����##5�� ������������� ���)

Page 77: Java in Datenbanksystemen

�� ��������#�������� ��

In Beispiel 3.3 wird zuerst der Vektor vektor1 definiert. Bei der Definition eines Vektorserlaubt die Java-Sprache auch die folgende Notation:

�� ���& �����

Der Vektor vektor2 wird definiert und gleichzeitig initialisiert. Bei der Initialisierungder Vektors v_neu wird der Zeiger, der auf den Vektor vektor2 zeigt, kopiert.

Die Anzahl der Elemente eines Vektors ist systemabhängig, d.h. der Anwender kanndie Anzahl der Elemente eines Vektors nicht definieren. Aus diesem Grund haben alleVektoren einen impliziten Wert – length –, der die Anzahl der Elemente enthält. Damitist es für den Anwender möglich, die tatsächliche Anzahl der Elemente eines Vektorszu ermitteln.

Die Sprache Java unterstützt sowohl eindimensionale als auch mehrdimensionale Vek-toren. Mehrdimensionale Vektoren werden genauso wie die eindimensionalen defi-niert und initialisiert. In Beispiel 3.3 wird auch ein zweidimensionaler Vektor namensmatrix definiert und initialisiert. Die letzte Zeile des Beispiels 3.3 zeigt die Initialisie-rung eines dreidimensionalen Vektors namens dreidim.

Alle alphanumerischen Datentypen der SQL-Sprache werden auf den Java-DatentypString abgebildet.

��� ���������&��������

Java unterstützt folgende Schleifenanweisungen:

� if/else

� for

� while bzw. do/while

� switch

Diese Anweisungen haben eine ähnliche Syntax und Bedeutung wie die gleichnami-gen Anweisungen bei den Sprachen C bzw C++. Mit Hilfe eines Beispiels werden wirdie beiden ersten Schleifenanweisungen (if und for) zeigen.

Beispiel 3.4

������7�&� �� ���##8����������������������� �������9��:��;� ����

���##�<����;����������� ���7�&� = ��

����##�%���>�������)�� �)�������&��� 1�,�����������

����� � ���,������� �?@A3'>B6�"�2�

����� � ���,������� ����3,�& ���"�!�

���������� � ��������������� ������������

������� �)�� �"�!�

������ �����&���(���;���

Page 78: Java in Datenbanksystemen

�$ ������������ ������������������� ���

���� ���� ���� �����CD���+����3,�& ������##��� ���E�8���������F�&� �G��������

##� H7��������8��������� ������5�� ��(�����6�D�� � ���F��� � ����

��##6��F��� � ������� ;=� �����?� ;������� ��

�����,������ ���"�!����I"�?@A3'>B6���++�

�����������,��)�� �J0�""�C�

���������������&���(���;���"���$��

���������������&���(���;���"����

����������)�� �"�)�� �$���

������������� ���� ���� ������+��D���+�)�� �+�&���(���;����

����������

����

��

Die Ausgabe des Beispiels 3.4 sieht folgendermaßen aus:

CD�!

!D�!

0D�0�$

-D�/�$

.D�0.�$

2D�!0C�$

In Beispiel 3.4 werden die Fakultäten der Ganzzahlen von 0 bis 5 berechnet und ausge-geben. Die in diesem Beispiel verwendete Methode println() haben wir schon inBeispiel 3.1 erläutert. Der Parameter der println()-Methode enthält den Konkatena-tionsoperator »+«, mit dem jede Ganzzahl und der entsprechende Fakultätenwertzusammen ausgegeben werden.

Der Wert der Konstante MAX_WERT spezifiziert, wie oft die for-Schleife ausgeführtwird. Der Modulo-Operator »%« wird benutzt, um diejenigen Ausgabenzeilen mit »*«zu kennzeichnen, die einen geraden Fakultätenwert haben.

Die Schleifenanweisung for im Beispiel 3.4 kann durch die folgende while-Anweisungersetzt werden:

������� ���"�!�����������##�5�� ����������

�����);�������I"�?@A3'>B6������##);���H��;���,�

�����������,��)�� �J0�""�C�

���������������&���(���;���"���$��

���������������&���(���;���"����

����������)�� �"�)�� �$���

������������ ���� ���� ������+��D���+�)�� �+�&���(���;����

����������++����������������##�5�&�����

���������

Page 79: Java in Datenbanksystemen

%�����&��������'���� ��������������()���**� �+

��' (������)������ �$����������������� *+����,,�

Nachdem man ein Java-Programm (wie das Programm in Beispiel 3.4) mit einem Text-editor eingetippt und gespeichert hat, kann die Übersetzung gestartet werden. DieVoraussetzungen für die Übersetzung sind, dass das Quellprogramm das Suffix».java« enthält und der Name des Programms mit dem Namen der Klasse, die dasmain-Programm beinhaltet, übereinstimmt. Die Übersetzung eines Java-Quellpro-gramms wird mit dem Programm namens javac durchgeführt. Damit wird die Über-setzung des Programms aus Beispiel 3.4 mit dem folgenden Kommando durchgeführt:

G�����7�&� �� ���G���

wobei Fakultaeten.java der Name der Datei ist, in der das Quellprogramm gespeichert ist.

Nach der Übersetzung des Quellprogramms wird der sogenante Java-Bytecodeerstellt. Beim Java-Bytecode handelt es sich um einen Zwischen-Code, der anschlie-ßend an jedem Rechner ausgeführt werden kann, der Java Virtual Machine (JVM)beherbergt. JVM stellt damit einen Übersetzer dar, der den Zwischen-Code in denMaschinen-Code des jeweiligen Rechners übersetzt. (JVM kann auch als Teil einesWeb-Browsers existieren.)

Nach der Übersetzung eines Java-Programms werden eine oder mehrere Dateien mitdem Suffix .class erstellt. Die Anzahl der .class-Dateien stimmt mit der Anzahl derKlassen, die im Quellprogramm definiert sind, überein.

Die Ausführung eines Java-Programms hängt davon ab, ob es sich beim Programm umein für sich unabhängiges Programm (mit der main-Methode) handelt, oder um einApplet. Bei einem Programm mit der main-Methode wird ein weiteres Java-System-programm namens java aufgerufen, um die Erstelllung des Maschinen-Codes und dieanschließende Ausführung desselben durchzuführen. Damit wird die Ausführung desZwischen-Codes des Beispiels 3.4 folgendermaßen durchgeführt:

G����7�&� �� ��

Die Ausführung eines Applets verläuft anders. Mit Hilfe eines Web-Browsers wirdeine HTML-Datei aufgerufen, die die Ausführung des Applets veranlasst. (Java-Applets werden in Kapitel 4 beschrieben.)

��'�� � *+"���

Ein Java-Programm kann eine oder mehrere Java-Klassen beinhalten. Ein solches Pro-gramm wird generell Übersetzungseinheit (compilation unit) genannt und in einerDatei mit dem Suffix .java gespeichert. Jede Übersetzungseinheit kann, wenn dasgewünscht wird, zusammen mit anderen Einheiten in einer Bibliothek gespeichertwerden. (Bibliotheken heißen bei Java Pakete.) In diesem Fall wird mit Hilfe derAnweisung

Page 80: Java in Datenbanksystemen

$, ������������ ������������������� ���

��&��������3�&� �

die Übersetzungseinheit, in der diese Angabe gemacht wurde, ein Teil des Paketsmein_paket. (Die package-Anweisung muss immer als erste Anweisung in der Dateierscheinen.)

Falls die in einem Paket existierenden Java-Klassen und ihre Methoden in einem Pro-gramm verwendet werden sollen, müssen sie importiert werden. Dies geschieht mitder import-Anweisung. Damit sieht die Einbeziehung aller Klassen des Paketsmein_paket in einem Java-Programm folgendermaßen aus:

���� �����3�&� �$�

Falls die import-Anweisung ausgelassen wird, muss jede verwendete Klasse undMethode eines Pakets vollqualifiziert geschrieben werden (mein_paket.Klassen_name(), z.B.), was den Programmieraufwand erhöht.

Eine Eigenschaft der Java-Sprache ist, dass das Java Development Kit dem Program-mierer sehr viele Klassen, die in Paketen gruppiert sind, zur Verfügung stellt. DieseSystempakete werden, genauso wie die Benutzerpakete, mit Hilfe der import-Anwei-sung in ein Java-Programm geholt. Die folgende Anweisung:

���� �G�����K��$�

stellt alle Klassen des vordefinierten Java-Pakets namens java.sql dem Programm, wosie geschrieben wurden, zur Verfügung. (Bei java.sql handelt es sich um ein Paket, dasKlassen für die Implementierung von Datenbankanwendungen enthält.)

��'�� � *������

Unterschiedliche Java-Dateien werden durch verschiedene Endungen (Suffixe) eindeu-tig gekennzeichnet. Wie schon erwähnt, hat eine Übersetzungeinheit (d.h. ein Java-Programm) das Suffix .java. Nach der Übersetzung wird für jede in der Übersetzungs-einheit existierende Klasse eine .class-Datei erstellt.

Eine weitere Gruppe stellen .jar-Dateien dar. Eine .jar-Datei ist ein Archiv, das mehrere.class-Dateien enthält, die eventuell komprimiert sind. Für die Erstellung eines solchenArchivs bietet Java das Dienstprogramm namens jar. Der Aufruf dieses Dienstpro-gramms könnte z.B. folgendermaßen aussehen:

G���H�,����;���G������(���;���!�����3�&� #$������

Mit dem obigen jar-Komando wird ein neues Archiv namens archiv erstellt. DieOptionen »c« und »f« werden (fast) immer gebraucht, weil die erste die Erstellungeines Archivs indiziert, während die zweite eine Datei (anstatt der Standardausgabestdout) als Ausgabe festlegt. Die Eingabe kann mehrere Quellen haben, die alsNamensliste nach dem Namen des Archivs erscheinen. verzeichnis1 definiert damit

Page 81: Java in Datenbanksystemen

%�����&��������'���� ��������������()���**� $-

ein Dateiverzeichnis, aus dem alle Dateien in das Archiv übernommen werden. Bei derzweiten Eingabequelle (mein_paket/*.class) handelt es sich um ein Java-Paket, ausdem alle .class-Dateien ins Archiv übernommen werden.

��'�� � *-,��������� �*-,������� ������

Die Voraussetzung für die Erstellung von Java-Programmen ist die Existenz des JavaDevelopment Kits (JDK) von JavaSoft oder eines äquivalenten Java-Interpreters bzw.Übersetzers. Das JDK der Firma JavaSoft befindet sich unter

; D##G����������#���� �#L*3G�&F���� �; �� bzw.

; D##G����������#G0��#

und kann von diesen Adressen entweder runtergeladen oder direkt benutzt werden.

Unter Umständen ist es möglich, dass JDK auf Ihrem System schon existiert. Um daszu überprüfen, muss das Kommando

G����H�������

ausgeführt werden. Falls die Systemausgabe etwa so aussieht:

G�������������!�0�!�

M�������*?�������N%8H!�0�!H@1��� ���� ;������

bedeutet es, dass JDK auf Ihrem Rechner installiert ist.

Die wichtigste Umgebungsvariable, die mit der Java-Sprache im Zusammenhangsteht, heißt CLASSPATH. Diese Variable enthält eine Liste von Dateiverzeichnissen,womit dem Java-Übersetzer mitgeteilt wird, wo Java-Klassenbibliotheken zu findensind. Mit dem Systemkommando:

�>6�MO@��F@6��"�JMO@��F@6�J�%DPG���P����MDPG���P����

werden z.B. in der Windows-Umgebung zwei Dateiverzeichnisse spezifiziert, wo Java-Klassenbibliotheken gespeichert sind.

�������

Bei den .jar-Dateien (bzw. .zip-Dateien) muss die CLASSPATH-Umgebungsvaria-ble den expliziten Namen der Datei (und nicht nur des Verzeichnisses, wo sichdiese Datei befindet) enthalten.

Page 82: Java in Datenbanksystemen

$. ������������ ������������������� ���

��. /�0�"��������������������,����������

Das wichtigste objektorientierte Konzept ist der Klassenbegriff. Eine Klasse ist eineSammlung von Instanzen (Objekten), die alle zu demselben Typ gehören. Java verfolgtden objektorientierten Ansatz sehr konsequent, in dem alles, was in Java existiert, eineInstanz ist. Das heißt, dass auch die primitiven Datentypen als Instanzen einer Klassebetrachtet werden.

Die Instanz einer Klasse ist in Wirklichkeit ein Zeiger, der auf den entsprechendenSpeicherplatz verweist. Generell werden neue Instanzen mit dem Schlüsselwort newerstellt. Alle nichtinitialisierten Instanzen haben den Wert null. (Dies gilt nicht für dieStandarddatentypen, die als Spezialfall betrachtet werden. Bei ihrer Initialisierungwird das Schlüsselwort new nicht verwendet, sondern sie werden mit Hilfe der auto-matic-Variablen und ohne Verwendung von Zeigern initialisiert.)

Alphanumerische Variablen vom Typ String können sowohl als Variablen eines primi-tiven Datentyps als auch als Instanzen der Klasse String betrachtet werden. Aus die-sem Grund ist es möglich, eine solche Variable auf zwei unterschiedliche Weisen zuerstellen. Beispiel 3.5 zeigt die möglichen Alternativen bei der Erstellung einer String-Variablen.

Beispiel 3.5

� ���������#$�Q�������� �����1�&�����5�� ��(��� ������R�$#

� ������"����, ��#$Q�������� �����+5�� �����������E���(���,����$#

� �������"���)�� ����������, ���#$Q�������� ������+�5�� �����������E������������

7����$#

Der Gültigkeitsbereich eines Zeigers, der auf eine Instanz zeigt, ist immer durch dasgeschweifte Klammerpaar, innerhalb dessen die Instanz liegt, definiert. (Dasselbe giltfür die Variable eines primitiven Typs.) Nach dem Verlassen des Gültigkeitsbereichsexistiert die Instanz weiter, der Zeiger aber nicht.

Beispiel 3.6

���� �4�"�!0�

����

������ �K�"�S/�

����� �������"���)�� ����������, ��

����

##�;����&�����������*��������4���������;���)�����1���������������������K�������

���;

��

Page 83: Java in Datenbanksystemen

/�0�1�������������� ���*������������� $�

��.�� �����������������1!���

Mit dem Schlüsselwort class wird ein neuer Typ erstellt. Dieser Typ wird benutzt, umeinzelne Instanzen der Klasse zu erzeugen. Beispiel 3.7 zeigt die Erstellung einer einfa-chen Klasse.

Beispiel 3.7

������T�%� ����

������ ���

������ � ��������������� ������������

�T�%� �����"���)�T�%� ������#$�>�� ������������5�� ��(�$#

����".U��#$'�� ()������)������ ����,������F�& �� � ���������; �$#

����������������

In Beispiel 3.7 wird eine Klasse namens NurDaten definiert. Im main-Teil dieser Klassewird eine Instanz d der Klasse mit Hilfe von new und einem Konstruktor erstellt. (DerBegriff des Konstruktors wird in Kürze ausführlich erörtert.) Anschließend wird demFeld i der Klasse NurDaten der Wert 47 zugewiesen. Diese Zuweisung erfolgt mitHilfe der Punktnotation:

&������3��� ��(�,����"�)�� �

In Beispiel 3.7 haben wir nur Felder einer Klasse betrachtet. Entsprechend den Feldernkönnen auch Methoden als Teil einer Klasse definiert und verwendet werden. Die all-gemeine Syntax von Methoden sieht folgendermaßen aus:

����V�&����)�� ����� ;����������@����� ����� ���

����������8W��������?� ;���

���������

Beispiel 3.8 zeigt eine Klasse, die auch Methoden enthält.

Beispiel 3.8

���� �G���� ���$�

�����������?������

���������� � �������������� ������������

�����

����� ���� ���� ����>������������7�& ������ %� �D��+�� %� �����

�����

���������� � ���� ������� %� ����

������M����������"���)�9��������M�����������

�������� ��

������������� ���������L,����� �M��������%@X3L73?LT6���

�������+���+� ���������L,����� �M��������?LT6���

��������+���+� ���������L,����� �M��������X>@B���

�����

Page 84: Java in Datenbanksystemen

$� ������������ ������������������� ���

Die Ausgabe des Beispiels 3.8 ist:

>������������7�& ������ %� �D�!�U�0CC!

In Beispiel 3.8 ruft die main()-Funktion eine statische Methode namens getDate() auf,welche das aktuelle Datum vom Typ String zurückliefert. Die Methode getDate() iststatisch deklariert, da von der Klasse Miniprog noch keine Instanz beim Aufruf exis-tiert. Diese Methode kann daher immer aufgerufen werden, d.h. auch ohne dass dieInstanz der zugehörigen Klasse existiert.

Die Methode getDate() instantiiert eine Instanz der Klasse Calendar, aus der mit Hilfeder get-Methode die einzelnen Werte für Tag, Monat und Jahr ausgelesen werden. Mitder statischen Methode valueOf() der String-Klasse werden diese Zahlen in eine Zei-chenkette konvertiert und konkateniert. Diese Zeichenkette wird dann zurückgegebenund mit Hilfe der println()-Methode ausgegeben.

Beispiel 3.9 zeigt eine Klasse, die die Systemeigenschaften liefert.

Beispiel 3.9

���� �G���� ���$�

�������������� ��5�,�

���

���������� � �������������� ������������

������

��������� ���� ���� ������)�%� �����

������F���� �����"���� ����� F���� ������

������##N����B� ����>��������� HF,���,�� � �����D

������� �����G���"���� F���� ��������� ���������� ;���

������##F���� ��������>����� ����;����D

������>����� ��������"������ �T�������

������� ���������

������##>����� �������;��,��

������);��������;��?���>����� ����

��������

��������������"��� �����������4 >����� ���

��������##G�����8�������������5�;�� ��������D

���������� ���� ���� ����8��D��+���+��'�� D��+��� F���� ��������

��������

������

Ein Teil der Ausgabe des Beispiels 3.9 sieht folgendermaßen aus:

'���@��C!�!UDC0D00�9?6+C0DCC�0CC!

8��D�G������ ���������'�� D�N����6?��0�B� ����>��������� 1�� �������>�� ���

8��D������� ���������� ;�'�� D�%DPG�&!�-PG��P���

8��D�G���������������'�� D�!�-�CHM

8��D�G��������������'�� D����?������� ����5���

8��D�G��������������'�� D�; D##G����������#

8��D�� ;������ ���'�� D��

Page 85: Java in Datenbanksystemen

/�0�1�������������� ���*������������� $!

8��D�,�������������&��'�� D������

8��D�G�����������,��� ���������'�� D�N����*�� ���?��;��������,��� ���

8��D���������'�� D�7DPN%<3<�;

8��D�G������ ������������'�� D�!�-�CHM

8��D�G�����������,��� �����������'�� D����?������� ����5���

8��D���������'�� D�'����)��0CCC

Am Anfang jedes Java-Programms (und damit auch am Anfang des Beispiels 3.9) wer-den alle notwendigen Klassen, die in Standardbibliotheken enthalten sind, mit Hilfeder import-Anweisung importiert. Damit lädt die Anweisung

������������ �G���� ���$

alle Klassen des Java-Pakets namens java.util. Die Anweisung

�������F���� �����"���� ����� F���� ������

besteht aus der Methode getProperties(), die eine statische Methode der KlasseSystem ist. Die Klasse System erzeugt Systemeigenschaften als eine Instanz der KlasseProperties. Aus diesem Grund können diese der Instanz p zugewiesen werden.

Die Klasse Properties enthält u.a. zwei Methoden – getProperties() und propertyNa-mes(), die in Beispiel 3.9 verwendet werden. Die Methode getProperties() hat einenalphanumerischen Schlüssel (key) als Parameter, der verwendet wird, um die angege-bene Eigenschaft in der Liste aller Eigenschaften zu suchen.

Die Methode propertyNames() liefert als Rückgabewert eine Instanz der Klasse Enu-meration. Das Ergebnis dieser Instanz ist eine Liste, die alle Eigenschaften aus derEigenschaftsliste enthält. Diese werden in der Instanz enum der Klasse Enumerationgespeichert und danach mit Hilfe der while-Anweisung ausgegeben. Die MethodehasMoreElements() der Klasse Enumeration wird im Programm verwendet, um dasEndkriterium der while-Schleife zu bilden. Genauso wird die Methode nextElement()derselben Klasse für das Holen der nächsten Eigenschaft (aus der Liste aller Eigen-schaften) benutzt.

In der letzten Anweisung des Programms

����� ���� ���� ����8��D��+�����+��'�� D��+���� F���� ��������

werden alle Systemeigenschaften (mit dem Namen des entsprechenden Schlüssels)ausgegeben. Dabei wird der Operator »+« als Konkatenationsoperator verwendet. DieOperatoren »+« und »+=« für den String-Datentyp sind die einzigen Operatoren, diein der Sprache Java überladen werden können.

Page 86: Java in Datenbanksystemen

$" ������������ ������������������� ���

��.�� ������"���

Der Begriff der Kapselung bedeutet, dass die Modellierung von Daten und Methodeneiner Klasse gemeinsam in einem Modul erfolgt. Um dieses Ziel zu erreichen, werdenvon Java folgende Sichtbarkeitsbegriffe unterstützt:

� keine Angabe (friendly)

� öffentlich (public)

� privat (private)

� protected

Jeder Sichtbarkeitsbegriff definiert den Zugriff auf eine Variable bzw. Methode. Auf einElement (Variable bzw. Methode), das als friendly d.h. ohne Sichtbarkeitsbegriff defi-niert ist, kann mit allen Methoden innerhalb des Pakets, zu dem es gehört, zugegriffenwerden. Weil eine Datei als Übersetzungseinheit immer zu einem Paket gehören muss,können alle Klassen, die gemeinsam (in einer Datei) implementiert sind, auf alle Ele-mente anderer Klassen dieser Datei zugreifen.

Ein öffentliches (public)-Element steht allen Klassen (und ihren Methoden) zur Verfü-gung. Damit definiert dieser Sichtbarkeitsbegriff die niedrigste Stufe, wie ein Elementvon dem Zugriff anderer Klassen geschützt werden kann. Auf der anderen Seite kenn-zeichnet private den höchsten Schutz für ein Element, weil ein private-Element nur vonden Methoden der Klasse, in der es sich befindet, benutzt werden kann.

Ein protected-Element ähnelt einem friendly-Element, mit einer zusätzlichen Eigen-schaft: Methoden aller Klassen, die als Unterklassen der Klasse mit dem protected -Ele-ment in der Klassenhierarchie existieren, haben auch Zugriff darauf. (Zusätzlich dazukönnen die Methoden der eigenen Klasse sowie Methoden aller Klassen, die im selbenPaket definiert sind, auf ein protected-Element zugreifen.)

Sichtbarkeitsbegriffe können auch verwendet werden, um den Zugriff auf einzelneKlassen festzulegen. Eine Klasse kann entweder public oder friendly sein. Jede public-Klasse ist öffentlich für alle anderen Klassen und damit auch für jede Client-Anwen-dung. Mit der friendly-Angabe wird der Zugriff auf eine Klasse nur für Klassen ausdemselben Paket ermöglicht. (Eine Klasse kann nicht private sein, weil dann keineandere Klasse auf sie zugreifen kann.)

In Bezug auf die Sichtbarkeit gibt es für die Klassen folgende Einschränkungen:

� nur eine einzige Klasse in einer Übersetzungseinheit kann public sein. (Der Grundfür diese Funktionalitätseinschränkung liegt darin, dass eine Übersetzungseinheitnur eine einzige öffentliche Schnittstelle nach außen haben soll.)

Page 87: Java in Datenbanksystemen

/�0�1�������������� ���*������������� $�

� der Name der public-Klasse in einer Übersetzungseinheit muss genau mit demNamen der Datei übereinstimmen. Das heißt, dass eine public-Klasse mit demNamen Eigenschaften in einer Datei namens Eigenschaften.java gespeichert wer-den muss.

��.�� �������"����

Wie wir schon am Anfang des Kapitels erwähnt haben, beinhaltet eine Java-Klasse Fel-der und Methoden. Methoden einer Klasse sind gewöhnlich öffentliche Funktionen,die den Zugriff auf private Elemente dieser Klasse ermöglichen. Eine spezielle Formvon Methoden stellen Konstruktoren dar. Sie haben denselben Namen wie Klassenund werden für die Initialisierung der Klasse verwendet. Obwohl Konstruktore keinerichtigen Methoden sind, haben sie gewisse Ähnlichkeiten mit diesen. Wie alle Metho-den haben Konstruktoren einen oder mehrere Parameter. (Im Unterschied zu Metho-den haben Konstruktore keine Rückgabewerte.)

Java, als eine objektorientierte Sprache, unterstützt das Überladen von Methoden unddementsprechend auch das Überladen von Konstruktoren. (Das Überladen vonMethoden heißt, dass ein System mehrere gleichnamige Funktionen auf Grund ihrerSignatur voneinander unterscheiden kann. Die Signatur einer Methode beinhaltet denNamen der Methode, die Anzahl und den Typ von Argumenten und eventuell denRückgabewert.) Deswegen kann ein Konstruktor mehrere Ausprägungen haben, diesich in der Anzahl und den Datentypen seiner Parameter unterscheiden.

Falls der Benutzer keinen einzigen Konstruktor für eine Klasse definiert, wird ein sol-cher implizit vom System erstellt. Dieser Standard-Konstruktor hat keine Parameterund wird deswegen no-arg (no argument)-Konstruktor genannt. Ein Standard-Kon-struktor kann auch von dem Benutzer explizit erstellt werden, falls dieser ein odermehrere weitere Konstruktore (mit Parametern) haben will.

�������

Nach den Java-Regeln wird der erste Buchstabe aller Methodennamen kleingeschrieben. Das gilt nicht für einen Konstruktor, weil er denselben Namen wie dieentsprechende Klasse hat (und dieser nach der Konvention mit dem Großbuchsta-ben anfängt).

�������

Java, im Unterschied zu C++, kennt keine Destruktore. (Destruktore sind Kon-strukte, die aufgerufen werden, falls eine Klasseninstanz gelöscht werden soll.) Fürdas Löschen von Instanzen wird bei Java die Systemkomponente namens garbagecollector verwendet.

Page 88: Java in Datenbanksystemen

$$ ������������ ������������������� ���

Beispiel 3.10

������7�������������

����� � ���,������� ���������"�Y!-�

�������� ��� �����;��� ������"����

������ �� ����� ���� F����

������ �� ������������� ����"�,�����

���������7���������������;��� ������"������

���������7������������� �����;��� �������

������� ;���;��� ������"�;��� ������

�����

���������7������������7������������,��

�������;��� ������"�,�;��� ������

�����

���������� ������� ���� ��������

��������� ���;��� ������

�����

��������������)��;��F���������� �)�� ��

��������,��� ����

������������� F����"�)�� �

�����

����������������;�� �>�����

���������� ���� ���� ����>�����

��������� ����"� ���

�����

����������������;�� �@����

���������� ���� ���� ����@����

��������� ����"�,�����

�����

���������� � ����� ��� 5%���

��������� �����������

�����

���������� ����� �� �������

������ �����)�� �����;��� �����+�7������������*������D��+���������

�����

�����������8�����������

���������� � �������������� �������������

����������� ���� ���� ���7�������������� 5%����

��������7������������,�"���)�7�������������T��������

����������� ���� ���� ���,��

��������,���;�� �>�����

��������,�)��;��F��������2��

��������,���;�� �@����

�����

Page 89: Java in Datenbanksystemen

������� ���� ����������� $+

Das Ergebnis des Beispiels 3.10 ist

Y!-

T������7������������*������D�Y!-

>��

@�

In Beispiel 3.10 ist eine Klasse namens Fernbedienung definiert, die insgesamt dreiKonstruktore hat. Der erste Konstruktor ist der Standard-Konstruktor, während diebeiden anderen je einen Parameter haben. Die Klasse enthält drei Felder (version, her-steller und lastProg) sowie sechs Methoden (getHersteller(), waehleProgramm(),schaltEin(), getID(), toString() und schaltAus()). Im main-Teil wird eine neue Instanzder Klasse Fernbedienung erstellt und mit dem Wert »Noname« initialisiert. Anschlie-ßend werden die Methoden schaltEin() und schaltAus() auf diese Instanz angewen-det.

Bei der Definition eines der überladenen Konstruktoren der Klasse Fernbedienungwird das Schlüsselwort this verwendet:

;���;��� ������"�;��� ������

Bei this handelt es sich um eine Referenz auf die aktuelle Klasseninstanz. DiesesSchlüsselwort ist notwendig, um die Zweideutigkeit zwischen dem gleichnamigenKlassenelement (in diesem Fall das Feld hersteller der Instanz der Klasse Fernbedie-nung auf der linken Seite der Zuweisung) und dem Argument des Konstruktors zubeheben.

��2 ��������������������

Klassenhierarchien (extended classes) werden in Java mit Hilfe des Schlüsselwortesextends spezifiziert, indem dieses Wort in jeder Unterklasse (vor der geschweiftenKlammer) und vor dem Namen der Oberklasse geschrieben wird.

Beispiel 3.11 zeigt eine Klassenhierarchie zwischen zwei Klassen: Fernbedienung (Bei-spiel 3.10) und MarkenFernbedienung.

Beispiel 3.11

������?��&��7�������������4 �����7������������

���������?��&��7������������7������������,��

�����������,��

�����

���������?��&��7������������� �����;��� �������

�����������;��� �������

�����

���������������& ������6��� �4 ���

��������,��� ����

Page 90: Java in Datenbanksystemen

+, ������������ ������������������� ���

������������� ���� ���� ����6��� �4 �������

�����

������������������� B�������� ���� ���1��� ���������

���������� ���� ���� ����T�;����+������+��,V���+��� ���+�����

�,���

��������� ��� ���

�����

���������� ����� �� �������

���������� �����)�� ��������� �� ������+��T�T������

�����

�����������8�����������

���������� � �������������� �������������

����������� ���� ���� ���7�������������� 5%����

��������7������������,�"���)�7�������������T��������

����������� ���� ���� ���,��

��������,���;�� �>�����

��������,�)��;��F��������2��

��������,���;�� �@����

��������##HHHHHHHHHHHHHHHHHHHHH

��������?��&��7������������,0�"���)�?��&��7�������������%��4����

��������,0���;�� �>�����

��������,0�)��;��F��������2��

��������,0��& ������6��� �4 ���

���������,�R,0��� B������-C1�Y��

��������������� ���� ���� ����B��������������� ����; ���

��������,0���;�� �@����

�����

Die Ausgabe des Beispiels 3.11 sieht folgendermaßen aus:

>��

6��� �4 ����

T�;���Y�-C������,

@�

Beispiel 3.11 zeigt einige wichtige Eigenschaften von Java-Klassenhierarchien. DieUnterklasse MarkenFernbedienung erbt alle Klassenelemente (Methoden und Felder)der Oberklasse Fernbedienung. Damit werden alle vier Methoden der Oberklasseauch als Methoden der Unterklassen betrachtet, es sei denn in der Unterklasse existierteine Methode mit dem gleichen Namen. In einem solchen Fall wird die Methode derUnterklasse auf alle Instanzen derselben angewendet. In Beispiel 3.11 existiert dieMethode toString(), die eine Redefinition der gleichnamigen Methode in der Ober-klasse darstellt. Damit wird diese Methode auf alle Instanzen der Klasse MarkenFern-bedienung angewendet.

Page 91: Java in Datenbanksystemen

������� ���� ����������� +-

Jede Unterklasse kann zusätzliche (eigene) Methoden enthalten. Solche Methoden sinddann spezielle Methoden der Unterklasse. In Beispiel 3.11 stellen die Methoden akti-viereTeletext() und setRecord() zwei spezielle Methoden der Unterklasse Marken-Fernbedienung dar.

Falls eine Methode in einer Unterklasse redefiniert wird, wird diese Methode auf alleInstanzen der Unterklasse angewendet. Trotzdem ist es manchmal notwendig, diegleichnamige Methode der Oberklasse innerhalb der Unterklasse zu verwenden. Fürdiesen Fall unterstützt die Java-Sprache das Schlüsselwort super. Mit super also wird(generell) eine Methode der Oberklasse explizit in der Unterklasse angesprochen.

Falls ein Programm eine Klassenhierarchie enthält, ist es manchmal empfehlenswert,für jede existierende Klasse der Klassenhierarchie die Methode main() zu definieren.Eine solche Vorgehensweise kann insbesondere beim Testen des ganzen Programmshilfreich sein.

��2�� ����������/�0��

Die meisten objektorientierten Systeme haben eine Klasse, die einzelne Klassenhierar-chien einer Anwendung zu einer einzigen baumartigen Struktur zusammenführt.Diese Klasse heißt generell Klasse aller Klasse und bei der Java-Sprache heißt sieObject. Alle Methoden der Klasse Object werden von allen anderen Java-Klassengeerbt.

Die wichtigsten Methoden der Klasse Object sind:

� public boolean equals (Object obj)

� Class getClass()

� String toString()

Die Methode equals() überprüft, ob eine Instanz zu der Instanz obj gleich ist. DieMethode getClass() gibt den Namen der Klasse, zu der die Instanz gehört, zurück. DieMethode toString() gibt die als Parameter angegebene Instanz in der alphanumeri-schen Form zurück.

�������

Methoden einer Oberklasse sollten als public oder protected definiert werden.(friendly-Methoden sind nicht geeignet, weil sie keinen Bezug zu Klassenhierar-chien haben.)

Page 92: Java in Datenbanksystemen

+. ������������ ������������������� ���

��2�� $����"������������ �3���� ��

In der Praxis kommt es oft vor, dass eine Klasse keine Instanzen hat, und nur alsgemeinsame Schnittstelle für alle ihre Unterklassen dient. Eine solche Klasse wirdabstrakte Klasse genannt. (Die oberste Klasse einer Klassenhierarchie wird oft beimEntwurf ohne Instanzen konzipiert, weil dadurch alle Instanzen an die Unterklassenverteilt sind.)

Dasselbe gilt auch für Methoden: Falls es für eine Methode keine Instanzen gibt, aufdie man sie anwenden kann, wird sie abstrakte Methode genannt. Sowohl die abstrak-ten Klassen als auch die abstrakten Methoden werden mit dem Schlüsselwort abstractexplizit deklariert.

Beispiel 3.12 zeigt eine abstrakte Klasse.

Beispiel 3.12

��� ��� �������7�������������

����� � ���,������� ���������"�Y!-�

������� ��� �������������;�� �>�����

������� ��� �������������;�� �@����

���������� � ����� ��� 5%���

��������� �����������

�����

���������� ����� �� �������

���������� �����)�� ������7������������*������D��+���������

�����

������T�����7�������������4 �����7������������

����������������;�� �>�����

����������� ���� ���� ����>�����

�����

����������������;�� �@����

����������� ���� ���� ����@����

�����

���������� ����� �� �������

���������� �����)�� ��������� �� ������+��T�T������

�����

�����������@�� ��� �

���������� � �������������� �������������

����������� ���� ���� ���7�������������� 5%����

��������7������������,�"���)�T�����7��������������

����������� ���� ���� ���,��

��������,���;�� �>�����

��������,���;�� �@����

�����

Page 93: Java in Datenbanksystemen

������� ���� ����������� +�

Ausgabe des Beispiels:

Y!-

7������������*������D�Y!-�T�T���

>��

@�

Die Klasse Fernbedienung selbst ist in Beispiel 3.12 als abstrakte Klasse definiert , weileine Instantiierung derselben nicht vorgesehen ist. Die einzigen Methoden dieserKlasse schaltEin() und schaltAus() sind nicht implementiert: Dies muss in einer Unter-klasse erfolgen.

Um die Klasse Fernbedienung zu verwenden, muss zuerst eine Unterklasse definiertwerden:

������T�����7�������������4 �����7�����������

Alle abstrakten Methoden der Oberklasse müssen in der Unterklasse NonameFernbe-dienung implementiert werden. (Im anderen Fall müsste die Unterklasse wieder alsabstrakte gekennzeichet werden.) In der Klasse Fernbedienung befindet sich eine sta-tische Methode getID(), die damit auch ohne Instantiierung aufgerufen werden kann:

��� ���� ���� ���7�������������� 5%����

Die toString()-Methode kann erst aufgerufen werden, sobald eine Instanz der KlasseFernbedienung vorliegt, also eine abgeleitete Klasse vorhanden ist und instantiiertwurde. Im Beispiel wird diese Methode durch die gleichnamige Methode der Unter-klasse überschrieben, jedoch innerhalb der toString()-Methode mit Hilfe des Schlüssel-wortes super aufgerufen.

��2�� ��������������#4�������%

Schnittstellen stellen »reine« abstrakte Klassen dar, d.h. die Implementierung einerSchnittstelle wird in den entsprechenden Unterklassen vorgenommen. Nur Elementeder primitiven Typen können in einer Schnittstelle definiert werden (als static undfinal). Eine Schnittstelle wird mit dem Schlüsselwort interface deklariert.

Das folgende Beispiel zeigt die Definition einer Schnittstelle.

Beispiel 3.13

�� ��,����7�������������

����� � ���,������� ���������"�Y!-�

����������������;�� �>�����

����������������;�� �@����

���������������& ������6��� �4 ���

�������������������Q�,,����� �)�� ��

������T�����7������������������� ��7������������

Page 94: Java in Datenbanksystemen

+� ������������ ������������������� ���

�������� ��7������������ ���� �

���������T�����7������������7������������,��� ���� ",���

����������������;�� �>�����

�������� ���� ���;�� �>�����

�����

����������������;�� �@����

�������� ���� ���;�� �@����

�����

���������������& ������6��� �4 �������

�������������������Q�,,����� �)�� ������

������?��&��7������������������� ��7������������

�������� ��7������������ ���� �

���������?��&��7������������7������������,��� ���� ",���

����������������;�� �>�����

�������� ���� ���;�� �>�����

�����

����������������;�� �@����

�������� ���� ���;�� �@����

�����

���������������& ������6��� �4 ���

�������� ���� ��& ������6��� �4 ���

������

�������������������Q�,,����� �)�� ��

�������� ���� ������Q�,,���)�� ��

�����

������7�����;��?��&�@�������� ��7������������

����������������;�� �>�����

����������� ���� ���� ����7�����;���?��&��@�)�����������;�� � ���

�����

����������������;�� �@����

����������� ���� ���� ����7�����;���?��&��@�)����������;�� � ���

�����

���������������& ������6��� �4 ���

����������� ���� ���� ����7�����;���?��&��@�(��� �6��� �4 ���

�����

�������������������Q�,,����� �)�� ��

����������� ���� ���� ����7�����;���?��&��@�(��� �F�������D��+)�� ��

�����

������7�����;��?��&�<�������� ��7������������

����������������;�� �>�����

����������� ���� ���� ����7�����;���?��&��<�)�����������;�� � ���

�����

����������������;�� �@����

����������� ���� ���� ����7�����;���?��&��<�)����������;�� � ���

�����

���������������& ������6��� �4 ���

����������� ���� ���� ����6��� �4 �����7�����;���?��&��<����; �� ��� V ( ���

�����

Page 95: Java in Datenbanksystemen

������� ���� ����������� +!

�������������������Q�,,����� �)�� ��

����������� ���� ���� ����7�����;���?��&��<�(��� �F�������D��+)�� ��

�����

�����������5� ��,�����

���������� � �������������� �������������

��������7������������,!�"���)�T�����7��������������)�7�����;��?��&�@����

��������7������������,0�"���)�T�����7��������������)�7�����;��?��&�<����

��������7������������,-�"���)�?��&��7��������������)�7�����;��?��&�<����

��������,!���;�� �>�����

��������,0��& ������6��� �4 ���##&�����B��& ���1����; �������� ���

��������,-��& ������6��� �4 ���

�����

Ausgabe des Beispiels:

7�����;���?��&��@�)�����������;�� �

6��� �4 �����7�����;���?��&��<����; �� ��� V (

Die hier deklarierte Schnittstelle kann, wie jede solche, nicht selbst instantiiert werden.Es werden lediglich Schnittstellenfunktionen deklariert, die von allen Unterklassenimplementiert werden müssen. Beispiel 3.13 entspricht einer fiktiven, sehr vereinfach-ten Fernbedienungsschnittstelle, die theoretisch von jedem Hersteller implementiertwerden kann und dann auch mit jedem Fernsehgerät funktionieren würde, solangedas Fernsehgerät und die Fernbedienung die gleiche Schnittstelle implementieren. DieUnterklasse Nonamefernbedienung beispielsweise würde alle Funktionen außer derMethode aktiviereTeletext() implementieren. (In dieser Methode ist der Funktions-rumpf leer.) In der der Unterklasse Markenfernbedienung hingegen würden wohl alleFunktionen implementiert.

Im Hauptprogramm kann jeder Fernseher über die Fernbedienung-Schnittstelle»bedient«, also angesprochen werden. Ob die jeweilige Methode implementiert ist,hängt vom jeweiligen Gerät, also der jeweiligen konkreten Schnittstellenimplementie-rung ab. Im Beispiel wird für die Kommunikation zwischen Fernbedienung undFernseher dem Fernbedienungs-Konstruktor die Instanz des entsprechenden Fernseh-gerätes mitgegeben.

��2�' +��!,������,�������

Polymorphismus in Java entspricht der Redefinition von Methoden. Dieser Begriffkennzeichnet den Fall, wo ein Methodenname für verschiedene Instanzen einer Klas-senhierarchie aufgerufen werden kann. Abhängig von der Klassenzugehörigkeit derInstanz wird die entsprechende Methodenimplementierung ausgewählt.

Die Redefinition von Methoden (d.h. der Aufruf der entsprechenden Methode, abhän-gig von der Klassenzugehörigkeit der Instanz) basiert auf dem Konzept des späten

Page 96: Java in Datenbanksystemen

+" ������������ ������������������� ���

(dynamischen) Bindens (late binding). Das späte Binden bedeutet, dass die Datentypenaller Elemente (Felder und Methoden) erst zur Laufzeit bekannt sind.

Alle Elemente in Java verwenden das dynamische Binden, bis auf Elemente, die alsfinal definiert sind. Das heißt, dass die Java-Sprache dem Benutzer die Option gibt, dieRedefinition von Methoden in seinen Programmen auszuschalten. Diese Lösung, d.h.den Polymorphismus als optionale Funktion anzubieten, ist sehr vernünftig, weil beikomplexeren Klassenhierarchien die Suche nach den entsprechenden Methoden inner-halb der Hierarchie sehr zeitaufwendig sein kann.

Beispiel 3.14

�� ��,����7�������������

����� � ���,������� ���������"�Y!-�

����������������;�� �>�����

����������������;�� �@����

���������������& ������6��� �4 ���

�������������������Q�,,����� �)�� ��

������7�����;��?��&�<�������� ��7������������

����������������;�� �>�����

����������� ���� ���� ����7�����;���?��&��<�)�����������;�� � ���

�����

����������������;�� �@����

����������� ���� ���� ����7�����;���?��&��<�)����������;�� � ���

�����

���������������& ������6��� �4 ���

����������� ���� ���� ����6��� �4 �����7�����;���?��&��<����; �� ��� V ( ���

�����

�������������������Q�,,����� �)�� ��

�������� ���� ���� ����7�����;���?��&��<�(��� �F�������D��+)�� ��

�����

������7�����;��?��&�<%��4���4 �����7�����;��?��&�<�

���������������& ������6��� �4 ���

����������� ���� ���� ����6��� �4 �7�����;���?��&��<�%��4����� �� � ���

�����

�����������F������;�

���������� � �������������� �������������

��������7�����;��?��&�<�,!�"���)�7�����;��?��&�<���

��������7�����;��?��&�<�,0�"���)�7�����;��?��&�<%��4����

��������7������������,��"���)�7�����;��?��&�<%��4����

��������,!��& ������6��� �4 ���

��������##����)����� ��� ���;�����&����& ��?� ;�����,���,��D

��������,0��& ������6��� �4 ���

��������,���& ������6��� �4 ���

�����

Page 97: Java in Datenbanksystemen

2������������� �������������(��� � +�

Ausgabe des Beispiels:

6��� �4 �����7�����;���?��&��<����; �� ��� V (

6��� �4 �7�����;���?��&��<�%��4����� �� �

6��� �4 �7�����;���?��&��<�%��4����� �� �

Um den Polymorphismus zu demonstrieren, wurde in Beispiel 3.14 die UnterklasseFernseherMarkeBDeluxe der Klasse FernseherMarkeB definiert, welche die Teletext-Funktionalität implementiert. Im Hauptprogramm werden nun beide Fernsehertypenals FernseherMarkeB deklariert. Außerdem wird zur Demonstration auch noch dieDeklaration als Fernbedienung vorgenommen, da diese Schnittstelle von jedem Fern-seher implementiert wird.

Der erste Aufruf der Methode aktiviereTeletext() gibt den Text der entsprechendenMethode in der Klasse FernseherMarkeB aus. Obwohl sich der zweite Aufruf dieserMethode wieder auf eine Instanz der Klasse FernseherMarkeB bezieht, wird durchdas späte Binden erkannt, dass es sich eigentlich um eine Instanz der Klasse Fernse-herMarkeBDeluxe handelt und dementsprechend wird die Methode aktiviereTele-text() dieser Klasse aufgerufen.

��5 6������������������� ���� *�����

In diesem Abschnitt werden weitere Eigenschaften der Java-Sprache beschrieben, diewir im weiteren Verlauf des Buches verwenden werden:

� Ausnahmen

� Ein- und Ausgabe

Die folgenden Unterabschnitte erläutern die oben genannten Eigenschaften.

��5�� $����,��

Die Ausnahmen (exceptions) dienen der Fehlerbehandlung. Die grundsätzliche Idee beider Java-Sprache ist, Fehler schon bei der Übersetzungszeit eines Programms (so weitwie möglich) abzufangen. Auf diese Weise wird versucht, aufgetretene Fehler so frühwie möglich zu entdecken, was den Programmier- und Testaufwand signifikant ver-ringert.

Diejenigen Fehler, die zur Übersetzungszeit nicht abgefangen werden, werden durchgewisse Formalitäten behandelt. Diese Formalitäten basieren auf vier Java-Anweisun-gen, die in Bezug zur Ausnahmebehandlung stehen:

� throw

� catch

Page 98: Java in Datenbanksystemen

+$ ������������ ������������������� ���

� try

� finally.

Die Anweisung throw löst eine Ausnahme explizit aus. Dabei werden folgendeSchritte ausgeführt:

� eine Instanz (der Klasse Throwable) wird neu erstellt

� die Abarbeitung des Programms wird gestoppt

� der Mechanismus für die Abarbeitung der Ausnahme (exception handler) über-nimmt die Arbeit und versucht das Problem zu lösen, damit das Programm weiterausgeführt werden kann.

Bei der Abarbeitung einer Ausnahme gibt es generell zwei Möglichkeiten: Sie kannentweder in einem catch-Block abgearbeitet werden, oder sie wird weitergeleitet, bissie abgearbeitet werden kann. Beispiel 3.15 zeigt die Abarbeitung einer Ausnahme, dieexplizit mit der throw-Anweisung ausgelöst wird und an die aufrufende Methodeweitergeleitet wird.

Beispiel 3.15

������>4�� !

�������� � �������������� �����������

�������� ;���!���

��

����������� � ���������� ;���!����

���##�������Z����� �Z�?� ;���1��������7�;������ �������� ��� 1�

�������&��� �����7�;���������

��������� ����

�������������� ;���0���

������������� �;��>4�� ����������� ���� ���� ����?����� ������ ;���0�

������������;� �����7�;�����������; ���

����������

��������

������������ � ���������� ;���0��� ;��)��>4�� �����

�����##�������?� ;������ �����1������ ;���-��������@���;������,�� 1

�������##��������@,����������,�,������?� ;���

����������� ;���-���

�������

����������� � ���������� ;���-��� ;��)��>4�� �����

����##;����)���������; ���;������T��HF��� ��H@���;�����(��

���������5� ������"����

����������� ���� ���� ����� �� ��������

��������

������

Page 99: Java in Datenbanksystemen

2������������� �������������(��� � ++

Die Ausgabe des Beispiels 3.15 ist:

?����� ������ ;���0�;� �����7�;�����������;

In Beispiel 3.15 wird zuerst gezeigt, wie die throw-Anweisung verwendet wird. DieMethode methode3() erzeugt explizit eine Ausnahme, die in ihrem Block nicht abgear-beitet werden kann, weil dort keine Fehlerbehandlung stattfindet. Dadurch wird dieAusnahme an die Methode methode2() weitergeliefert, die sie (weil sie auch keineFehlerbehandlung ermöglicht) an die Methode methode1() weiterleitet. Durch dieExistenz des try-Blocks in der Methode methode1() wird dort der Fehler behandeltund die catch-Anweisung ausgeführt.

Bei der Fehlerbehandlung kann jede Instanz der Klasse java.lang.Throwable geworfenwerden. Für verschiedene Fehlertypen werden gewöhnlich unterschiedliche Ausnah-meklassen verwendet. Die Klasse Throwable ist die Basisklasse für alle anderen Aus-nahmeklassen, d.h. alle anderen Ausnahmen sind Erweiterungen der KlasseThrowable.

Die zweite wichtige Ausnahmeklasse ist Exception. Sie ist die direkte Unterklasse derKlasse Throwable, und sie enthält ein alphanumerisches Attribut, das den Fehlerbeschreibt (siehe Beispiel 3.16). Die zweite direkte Unterklasse der Klasse Throwableheißt Error. Diese Klasse wird aufgerufen, falls ein schwerwiegender Fehler auftritt,den eine normale Anwendung nicht abfangen kann.

Wie wir schon in Beispiel 3.15 gesehen haben, erfolgt die Behandlung einer Ausnahmedurch einen try/catch/finally-Block. Die grundsätzliche Idee bei diesem Block ist, dassder Benutzer etwas probiert (try); falls der Versuch eine Ausnahme wirft, wird sie (mitcatch) abgefangen und anschließend (finally) werden die Aufräumarbeiten durchge-führt.

Beispiel 3.16 zeigt einen try/catch-Block.

Beispiel 3.16

�����������@���;��3�������!

������������� � �������������� ������������

�����

���� �����##;����)���������; ���;�����T��HF��� ��H@���;�����(��

������������� ������"����

�������������� ���� ���� ����� �� ��������

���������

������ �;��>4�� ������

������������� ���� ���� ����@���;�������,��������

���������##��� ?�������������� �����7�;���������� �4 �(�V�&

������������� ���� ���� ��������� ?��������D���+����� ?����������

����������##� �� ���������� �&�(��<���;�������(�V�&

������������� ���� ���� ������ �� ������D���+��� �� ��������

Page 100: Java in Datenbanksystemen

-,, ������������ ������������������� ���

����������##���� � ��&6�������� �������� ��������,���� ������

������������� ���� ���� ��������� � ��&6������D����

��������������� � ��&6�������

���������

������

Die Ausgabe ist:

@���;�������,�����

���� ?��������D����

�� �� ������D�G���������T��F��� ��>4�� ���

����� � ��&6������D

G���������T��F��� ��>4�� ���

�������� �@���;��3�������!������@���;��3�������!�G���D�U�

In Beispiel 3.16 wurden neben einem try/catch-Block auch einige Methoden der KlasseException verwendet. Die Methode getMessage() gibt den Fehlermeldungstextzurück, während die Methode toString() eine kurze Beschreibung der Ausnahme aus-gibt. Die Methode printStackTrace() gibt zusätzliche Information, wie z.B. die Pro-grammzeile, wo der Fehler aufgetreten ist (siehe Ausgabe).

��5�� ���*��� �$������ �������

Java-Ein- und Ausgabeklassen befinden sich in einem Paket namens java.io. Diegrundsätzliche Eigenschaft von Java ist, dass sehr viele Klassen für die Ein- und Aus-gabe existieren und dass alle Klassen in zwei Gruppen (Eingabe- und Ausgabeklassen)unterteilt sind.

Die Ein- und Ausgabeoperationen bei Java basieren auf den sogenannten Strömen(streams). Ströme sind Folgen von Bytes bzw. Zeichen. Ein Strom wird generell im Rah-men eines Konstruktor-Aufrufs zuerst geöffnet, danach gelesen bzw. beschrieben undletztendlich geschlossen.

Ströme können in:

� Byte-Ströme (8Bit)

� Zeichenströme (16Bit)

unterteilt werden.

Byte-Ströme sind ein Teil von Java 1.0, während Zeichenströme seit Java 1.1 existieren.

�������

Die Philosophie, dass Ein- und Ausgabe nicht direkt zum Sprachumfang gehören,sondern ausgelagert werden, hat Java von den Sprachen C und C++ übernommen.

Page 101: Java in Datenbanksystemen

2������������� �������������(��� � -,-

Die oberste Klasse für die Dateneingabe bei Java 1.0 heißt InputStream, während dieentsprechende Klasse für die Datenausgabe OutputStream ist. Bei diesen beiden Klas-sen handelt es sich um abstrakte Klassen, so dass alle ihre Methoden in den Unterklas-sen implementiert sind.

Die oberste Klasse für die Dateneingabe bei Java 1.1 heißt Reader, während die ent-sprechende Klasse für die Datenausgabe Writer ist. (Abbildung 3.1 zeigt die Klassen-hierarchien mit den obersten Klassen Reader und Writer.)

Weil die Beschreibung aller Ein- und Ausgabeklassen den Umfang dieses Buchessprengen würde, werden wir zwei Beispiele zeigen, welche die in diesem Buch ver-wendeten Ein- und Ausgabeklassen symbolisieren. Für weitere Informationen inBezug auf Ein- und Ausgabe wird auf das Buch von Bruce Eckel (siehe Literaturver-zeichnis) verwiesen.

Beispiel 3.17 zeigt die generelle Art, wie in JDBC- und SQLJ-Programmen, die in die-sem Buch verwendet wurden, das Lesen von Sätzen durchgeführt wird.

Beispiel 3.17

� ������K�!�"����)�<,,����B��������)

5� � ����B��������� �������������O������

'����������3-4������-3-����(�����'������1����������������-3-

Page 102: Java in Datenbanksystemen

-,. ������������ ������������������� ���

System.in stellt den Standardeingabestrom einer Anwendug dar. In jeder Applikationist dieser statische Eingabestrom der Klasse InputStream über das System-Objekt vor-handen. Mit der Instanz der Klasse InputStream erzeugt man mittels

���)�5� � ����B��������� ������

eine Instanz der Klasse InputStreamReader, aus der man über den BufferedReader-Konstruktor eine Instanz der Klasse BufferedReader erzeugt. Dieser gepufferte Einga-bestrom liest von der Standardeingabe und erlaubt beispielsweise das Einlesen einerZeile bis zum Zeilenende mit Hilfe der Methode readLine(). Der Rückgabewert ent-spricht einer String-Variablen mit den eingegebenen Daten am Bildschirm.

Beim Schreiben von Sätzen werden in diesem Buch generell zwei Methoden der KlassePrintStream verwendet: print() und println(). Diese beiden Methoden werden für dietextuelle Ausgabe von Daten der Java-Standarddatentypen sowie die InstanzenSystem.out und System.err benutzt. (out und err sind, gemeinsam mit in, drei Felderder Klasse java.lang.System. Sie entsprechen der Standardausgabe, Fehlerausgabeund Standardeingabe, in dieser Reihenfolge.)

Beispiel 3.18 zeigt die beiden Methoden println() und print(), die wir im weiteren Ver-lauf des Buches für die Implementierung der Datenausgabe generell verwenden wer-den.

Beispiel 3.18

��� ���� ���� �����%����� ������@���������

��� ���� ���� ����3��"���+��������

Der einzige Unterschied zwischen den in Beispiel 3.18 gezeigten Methoden ist, dassdie erste nach der Beendigung der Ausgabe ein end of line macht, während die zweiteweitere Ausgaben in derselben Zeile erwartet.

Die Ein- und Ausgabefehler werden genauso wie alle anderen Fehler der Java-Sprachemit Hilfe von Ausnahmen behandelt. Für diesen Zweck steht die Klasse java.io.IOEx-ception zur Verfügung. Diese Klasse ist die direkte Unterklasse der Klasse Exception.Es handelt sich dabei um eine abstrakte Klasse, die zahlreiche Unterklassen hat. Damitwerden alle spezifischen Ein- und Ausgabefehler durch die Unterklassen behandelt.

�������

Der Grund für dieses etwas komplizierte Vorgehen liegt im Aufbau der Java-Ströme. InputStream an sich ist nicht gepuffert und enthält beispielsweise nurrudimentäre Methoden zum Lesen. Mit der vorgestellten Methode kann manjedoch mit maximaler Effizienz und sehr einfach auf den Standardeingabestromzugreifen.

Page 103: Java in Datenbanksystemen

5���**��������� -,�

��7 8��,,��������

In diesem Kapitel wurden ausschließlich diejenigen Eigenschaften der Java-Sprachebeschrieben, die als Basis für den Rest des Buches verwendet werden. Die beschriebe-nen Eigenschaften haben wir in drei Teile unterteilt:

� allgemeine (nichtobjektorientierte)

� objektorientierte

� spezielle.

Dieses Kapitel schließt den Einführungsteil des Buches ab. Das vierte Kapitel ist dasAnfangskapitel des Teils über JDBC.

Page 104: Java in Datenbanksystemen
Page 105: Java in Datenbanksystemen

�����������

Page 106: Java in Datenbanksystemen
Page 107: Java in Datenbanksystemen

� ����������

��� ����������

JDBC (Java Database Connectivity) ist ein von Sun Microsystems spezifiziertes Verfah-ren, das eine einheitliche Schnittstelle auf der Basis der Java-Sprache zu Datenbankendarstellt. JDBC funktioniert von der Idee her ganz ähnlich wie ODBC.

ODBC (Open Database Connectivity) ist eine standardisierte Schnittstelle, die einheit-liche Zugriffe auf Datenbanken (mit Hilfe von Anweisungen, die sich an die SQL-Spra-che anlehnen) ermöglichen. ODBC steht immer als eine Laufzeitbibliothek (odbc.dll)zur Verfügung, die als Treibermanager bezeichnet wird. Der Zugriff auf eine Daten-bank erfolgt über einen spezifischen Treiber.

Analog zu ODBC öffnet eine Anwendung mit Hilfe von JDBC eine Datenbank einesbeliebigen Datenbanksystems, vorausgesetzt, dem Java-Programm steht ein JDBC-Treiber für dieses Datenbanksystem zur Verfügung.

Trotz dieser Ähnlichkeit existieren auch einige Unterschiede zwischen ODBC undJDBC. ODBC ist eine weit verbreitete Schnittstelle, die durch das X/OPEN-Gremiumauch als SQL CLI (Call Library Interface) standardisiert ist. Weiterhin ist sie eine C bzw.C++- orientierte Sprache, was bedeutet, das sie Zeiger verwendet. Demgegenüber istJDBC Java-orientiert und, wie es für eine objektorientierte Sprache angemessen ist, ver-wendet sie Klassen, Klasseninstanzen, Attribute (Felder) und Methoden.

Nach der in Kapitel 1 dargestellten Unterteilung aller Datenbankanwendungen stelltJDBC ein CLI dar. Bei einer solchen Schnittstelle (siehe Abbildung 4.1) werden dieSQL-Anweisungen im Programm als Zeichenketten bearbeitet und zur Ausführunggebracht. Rückgabewerte und Ergebnismengen werden durch Methodenaufrufe ermit-telt und nach der geeigneten Typkonvertierung im aufrufenden Programm weiterver-arbeitet. Der JDBC-Treibermanager bietet ein Grundgerüst für JDBC-Treiber. KonkreteJDBC-Treiber für spezifische Datenbanksysteme enthält JDBC jedoch nicht. Solche Trei-ber stammen von den Datenbankherstellern oder von Middleware-Spezialisten.

�������

JDBC ist im Unterschied zu ODBC auch robuster, weil sie Java-Ausnahmen ver-wendet.

Page 108: Java in Datenbanksystemen

��� ������������� ��

����� �������������

JDK (Java Development Kit) ist ein Programmierpaket, das folgende Komponenten ent-hält:

� JDBC Treibermanager

� JDBC Treiber Test Suite

� JDBC-ODBC-Bridge

� JDBC API.

Der JDBC Treibermanager ist diejenige Komponente von JDK, die für die Verbindungzwischen einem JDBC-Programm und der Datenbank verantwortlich ist. Treiber Test-Suite hat die Aufgabe, JDBC-Treiber auf ihre Funktionalität hin zu überprüfen. Nurdiejenigen Treiber, die der Überprüfung standhalten, werden »JDBC compliant«bezeichnet. Mit diesem Begriff werden alle Implementierungen von JDBC genannt, dieden entsprechenden Test der Firma JavaSoft bestanden haben. U.a. wird beim Testüberprüft, ob der getestete Treiber alle Klassen und Methoden von JDBC API unter-stützt. (Die JDBC-ODBC-Bridge ist ein Treiber, der im nächsten Abschnitt erläutertwird.)

Das JDBC API (Application Programing Interface) bietet einen Universaldatenzugriff fürdie Programmiersprache Java. Diese Programmierschnittstelle kann als low levelbezeichnet werden, weil die SQL-Anweisungen direkt ausgeführt werden. Der Vorteildieses Verfahrens ist, dass die Schnittstelle einfach zu verstehen ist, andererseits sinddie Kenntnisse der SQL-Sprache unbedingt nötig.

���������������������������������

Page 109: Java in Datenbanksystemen

������ ��!

Die Version 2.0 dieses APIs, die in JDK Version 1.2 enthalten ist, kann praktisch aufjede mögliche Datenquelle von den relationalen Datenbanken über Tabellenkalkula-tionsprogramme bis hin zu flachen Dateien zugreifen. Die JDBC-Technologie liefertdamit eine einheitliche Basis, auf der Hilfsmittel und alternative Schnittstellen aufge-baut werden können.

Das JDBC 2.0 umfasst zwei Pakete: das�java.sql�Paket, bekannt als das Kern API unddas javax.sql�Paket, bekannt als die JDBC-Standarderweiterung. (Der Buchstabe xsteht für eXtended, also erweitertes Paket.) Die JDK 1.2 Standardausgabe schließt denKern des JDBC 2.0 und den JDBC-ODBC-Treiber mit ein.

����� ������������� !�"�#�

Generell gesehen ist ein Treiber eine Softwarekomponente, die im Allgemeinen dieKommunikation zwischen einer Datenbankanwendung und einem Zieldatenbank-system ermöglicht. (In Ausnahmefällen kann es sich beim Zielsystem um eine Dateioder ähnliches handeln.) Aus diesem Grund muss ein JDBC-Treiber zwei Aufgabenerfüllen:

� die Unterstützung der JDBC-Funktionalität

� die Unterstützung des SQL-Sprachumfangs.

Eine JDBC-Schnittstelle hat zahlreiche Funktionen, die nicht alle von einem Treiberunterstützt werden müssen. Das typische Beispiel ist die Funktionalität von JDBC 2.0,die nicht in ihrem gesamten Umfang von allen Treibern unterstützt wird.

Ein JDBC-Treiber kann nicht den Sprachumfang aller existierenden Datenbanksystemeunterstützen, weil diese sehr viele Unterschiede aufweisen. Das typische Beispiel hierist ein nativer JDBC-Treiber, der ausschließlich den Sprachumfang des spezifischenDatenbanksystems kennt.

Dementsprechend ist ein JDBC-Treiber eine Softwarekomponente, die den Zugriff voneiner Datenbankanwendung, die in der Java-Sprache geschrieben ist, zu einem Ziel-datenbanksystem ermöglicht. Damit stellt der JDBC-Treiber für den Client eine einheit-liche Java-Schnittstelle zur Verfügung. (Jeder Treiber ist auf ein bestimmtesDatenbanksystem bzw. auf ein bestimmtes Zugriffsverfahren zugeschnitten.)

Es gibt vier verschiedene JDBC-Treibertypen:

� JDBC-ODBC-Treiber (Typ 1)

� von einem Hersteller implementierter Treiber (Typ 2)

� JDBC-Netztreiber (Typ 3)

� native JDBC-Treiber für Datenbanksysteme (Typ 4).

Page 110: Java in Datenbanksystemen

��� ������������� ��

Ein JDBC-ODBC-Treiber basiert auf einer Verbindung zwischen einem auf dem Clientinstallierten spezifischen ODBC-Treiber der eingesetzten Datenbank und dem JDBC-Treiber (siehe Abbildung 4.2). Diese Lösung ist gleichzeitig die einfachste, weil sie aufeinen existierenden ODBC-Treiber aufgesetzt wird. Sie besitzt auch den Vorteil, bereitszu einem frühen Zeitpunkt auf sämtliche ODBC-Datenbanken zugreifen zu können.

Im Gegensatz zu den oben genannten Vorteilen hat diese Lösung auch einen gewichti-gen Nachteil: Der JDBC-ODBC-Treiber besteht nicht ausschließlich aus Java-Bytecode,sondern zu einem großen Teil auch aus dem ODBC-Treiber, der gewöhnlich in Cgeschrieben ist. Daher ist er nicht portabel. Zusätzlich dazu ist diese Lösung für denEinsatz im Internet eher ungeeignet, da sie die Installation des Treibers auf dem Clientvoraussetzt, bevor die Java-Anwendung auf eine relationale Datenbank zugreifenkann.

Typ 2-Treiber sind herstellerspezifische Treiber, die Java verwenden, um Funktioneneiner Zugriffsschnittstelle aufzurufen, die die Verbindung zur Datenbank ermöglichen(siehe Abbildung 4.2). Diese Treiber sind also ebenfalls von der Client-Software abhän-gig. Die Vorteile eines Typ 2-Treibers sind, dass er sich einfach und schnell implemen-tieren lässt. Damit ist die Benutzung eines solchen Treibers attraktiv für einenDatenbankhersteller: Der Hersteller nimmt den beispielsweise in C geschriebenen Trei-ber seines Datenbanksystems und setzt eine JDBC-Schicht obenauf. Andererseits istdieser Treibertyp für den Einsatz im Internet nicht geeignet (weil der Teil des Treibers,der in C geschrieben ist, nicht portabel ist).

Generell lässt sich sagen, dass herstellerspezifische Treiber nur für den Zugriff auf einherstellereigenes Datenbanksystem verwendet werden können. Aus diesem Grundkann man diesen Treiber als eine plattformspezifische Übergangslösung betrachten(bis ein rein in Java geschriebener Treiber zur Verfügung steht).

Im Unterschied zu den beiden erstgenannten Treibertypen verwenden JDBC-Netztrei-ber die Netzwerkprotokolle des Java Development Kits, um eine Verbindung zu einerServer-Komponente auf dem Web-Server herzustellen (siehe Abbildung 4.2). Bei die-sen Treibern kann es sich um die vom Anwender selbstentwickelte Komponente oderum kommerzielle Middleware-Produkte handeln. Die Server-Komponente übersetztBefehle in datenbankspezifische Anfragen und schickt diese an die Datenbank.

Diese Lösung hat zwei Vorteile: Erstens muss auf der Client-Seite kein Treiberteilinstalliert werden, was eine signifikante Zeitersparnis mit sich bringt. Weiterhin hatdiese Lösung den Vorteil, dass nur die Server-Komponente, nicht aber die Datenbankauf demselben Rechner wie der Web-Server laufen muss.

Der JDBC-Netztreiber ist ein hundertprozentiger Java-Treiber, der die größtmöglicheFlexibilität von allen vier Treibertypen bietet. Damit fügt sich dieser Treibertyp nahtlosin das Dreischichtenmodell (siehe den Hinweis unten) ein. Er kommuniziert über das

Page 111: Java in Datenbanksystemen

������ ���

Netzwerk mit einer Middleware, die sich um alles weitere kümmert. (Middleware ist,wie der Name schon sagt, eine Software-Komponente, die eine Mittlerfunktion hat.)Die Middleware selbst muss nicht aus Java-Code bestehen, sondern kann in einerbeliebigen Programmiersprache geschrieben sein. Für das reibungslose Funktionierenist lediglich das von Client und Middleware gemeinsam unterstützte Kommunika-tionsprotokoll erforderlich. (Die Middleware an sich stellt eine zusätzliche Software-ebene dar, was die Komplexität der Lösung erhöhen kann.)

Der native JDBC-Treiber ist ebenfalls ein reiner Java-Treiber, entspricht aber eher demZweischichten- statt dem Dreischichtenmodell. (Beim Zweischichtenmodell werdenzwei der drei Logikteile (gewöhnlich die Geschäfts- und Datenlogik) auf einem Rech-ner zusammen bearbeitet.) Treiber dieses Typs entstehen in den Entwicklungslabors

�����������"������� �#$�����%&��

�������

Eine Anwendung beinhaltet drei Teile: Präsentationsteil oder Präsentationslogikgenannt, Geschäftslogik (auch Anwendungslogik genannt) und Datenlogik. Beieinem Dreischichtenmodell wird jeder der oben genannten Teile einer Anwendungauf einem separaten Rechnerteil bearbeitet: die Präsentationslogik auf dem Client,die Geschäftslogik auf dem Applikations-Server und die Datenlogik auf demDatenbank-Server. Damit bilden der Client, der Applikations-Server und derDatenbank-Server drei unterschiedliche Schichten.

Page 112: Java in Datenbanksystemen

��" ������������� ��

der Datenbankhersteller, die einen rein in Java implementierten JDBC-Treiber benöti-gen und ihren als Übergangslösung gedachten Typ 2-Treiber ablösen möchten. NativeTreiber verwenden das Netzwerkprotokoll des Datenbanksystems, um eine direkteVerbindung zur Datenbank einzurichten. Verfügt die eingesetzte Datenbank über eineJDBC-Schnittstelle, werden sie in der Regel vom Datenbankhersteller mitgeliefert. Diesist natürlich eine sehr effiziente Lösung für den Einsatz im Internet, da diese Java-Trei-ber übers Netz nachgeladen werden können und deswegen keine zusätzliche Softwareauf dem Client erforderlich ist. Allerdings verlangen die Sicherheitsbestimmungenvon Java, dass in diesem Fall die Datenbank auf demselben Rechner zu erreichen istwie der Web-Server, von dem die Anwendung stammt. (Alternativ sind aber auchProxy-Lösungen möglich, wie der ConnectionManager von Oracle, welche die Anfra-gen auf dem Web-Server an den Datenbank-Server umleiten.)

Während ein nativer JDBC-Treiber aus der Sicht des Anwendungsentwicklers als einmonolithisches Stück Java-Software erscheint, ist die interne Struktur sehr viel komple-xer. Schließlich kann der Treiber in seiner Eigenschaft als Java-Klasse nicht unmittelbarMethoden des Datenbanksystems aufrufen, es sei denn, dass das Datenbanksystem inJava implementiert ist. Zwischen einem Treiber und einem Datenbanksystem mussebenfalls eine Middleware-Komponente liegen, allerdings mit dem Unterschied, dasses sich hier um eine herstellerspezifische interne Schicht handelt, die nach außenunsichtbar ist und dem Anwendungsprogrammierer unzugänglich bleibt. (IBM bei-spielsweise bietet für seine AS/400-Maschinen unter der Bezeichnung JT400 eine Java-lmplementierung an. Nutzt ein Client, der etwa auf einem Sun-Rechner läuft, denJDBC-Treiber für die AS/400, kommuniziert dieser über das Netz per TCP/IP mit derAS/400, loggt sich ein, verbindet sich mit dem DB2-Datenbanksystem und greift auf dieDaten zu.)

��� �����$���������������!���%%�

Eine Datenbankanwendung kann generell auf zwei unterschiedliche Arten implemen-tiert werden:

� mit Hilfe der eingebetteten SQL-Anweisungen

� als Call Library Interface-Programm.

Unabhängig davon, welche Programmierart gewählt wird, werden bei der Implemen-tierung eines Datenbankprogramms immer die folgenden Schritte durchgeführt:

1. die Erstellung der Verbindung zu der Datenbank und das Einloggen in das System

2. die Erstellung der SQL-Anweisungsfolge

3. das Senden der Anweisungsfolge zum Datenbank-Server und ihre Ausführung

Page 113: Java in Datenbanksystemen

������������������ �#'�(���))� ��*

4. die reihenweise Verarbeitung der Ergebnisse

5. die Ausgabe der Ergebnisse

6. das Schließen der Verbindung zum Datenbank-Server.

Zusätzlich zu den sechs oben genannten Schritten existiert bei den Anwendungen, dieeinen Treiber verwenden, ein zusätzlicher Anfangsschritt: den Treiber laden. (WeilJDBC eine Schnittstelle ist, die den Treibereinsatz verlangt, ist dieser Schritt auch beiJDBC notwendig.)

Abbildung 4.3 zeigt die graphische Darstellung der o.g. Schritte zusammen mit dendazugehörigen JDBC-Klassen und ihren Methoden.

Folgende Abschnitte beschreiben separat alle diese Schritte. (Der zweite und der dritteSchritt werden gemeinsam in einem Abschnitt erörtert.)

����� �������������

Bevor mit JDBC auf eine Datenbank zugegriffen werden kann, muss zunächst eine Ver-bindung zu ihr hergestellt werden. Dazu muss der Datenbanktreiber geladen, initiali-siert und mit Hilfe des Treibermanagers eine Verbindungsinstanz erstellt werden. DieVerbindungsinstanz bleibt während der gesamten Verbindung bestehen und dient alsLieferant für spezielle Instanzen zur Abfrage und Veränderung der Datenbank. AlleKlassen zum Zugriff auf die JDBC-Schnittstelle liegen im Paket java.sql, das amAnfang des Programms mit der Anweisung

��������� �����

importiert werden muss.

Das Laden des Treibers kann auf zwei verschiedene Weisen durchgeführt werden:

� explizit

� automatisch.

Folgende Unterabschnitte beschreiben die beiden Varianten.

�&#��"�����'�������������������

Das explizite Laden einer Treiberklasse kann:

� durch den Aufruf der Methode forName der Klasse Class

� durch die Erstellung einer Instanz der Klasse Driver

durchgeführt werden.

Page 114: Java in Datenbanksystemen

��� ������������� ��

Die static-Methode forName� liefert eine Instanz der Klasse Class, die durch einenString-Parameter dargestellt ist. Die Syntax dieser Methode sieht folgendermaßen aus:

������� ������� ������������������ ������������ ��� ��� ���!"#�������

�����������*�������������������������+��,������-����)��� ��)&��)�����,��

Page 115: Java in Datenbanksystemen

������������������ �#'�(���))� ��.

Beispiel 4.1 zeigt zwei JDBC-Anweisungen, mit denen Treiber explizit geladen werdenkönnen.

Beispiel 4.1

�� ��������$ ���!����!���%!��&!��'�����$���((%')��&')��*�������� ��������$�&+�����!�,�!�������'),'�����$���((�������*-��.�*������

Mit der ersten Anweisung in Beispiel 4.1 wird ein JDBC-ODBC-Treiber geladen, der alsVerbindung zu allen Datenbanksystemen verwendet werden kann (unter der Voraus-setzung, dass der entsprechende ODBC-Treiber die Verbindung zum ausgewähltenDatenbanksystem herstellt). Im zweiten Beispiel wird ein nativer Treiber der FirmaIBM geladen, der nur die Verbindung zu einem DB2-System dieser Firma ermöglicht.

Das zweite explizite Verfahren verwendet eine Instanz der Klasse Driver und dieMethode registerDriver() um einen Treiber zu laden. Beispiel 4.2 zeigt die Erstellungeiner solchen Instanz.

Beispiel 4.2

'������!���/������&+�����!�,�!�������'),'��������'�����+��������� ���'������!����

Das Laden des Treibers mit Hilfe einer Instanz der Driver-Klasse hat einen (möglichen)Vorteil im Vergleich zum Aufruf der Methode forName(): Falls der angegebene Treibernicht vorhanden ist, wird bei dieser Methode eine Fehlermeldung zur Übersetzungs-zeit ausgegeben (»Cannot resolve symbol: Class <Treiberklasse>«). Damit hat man beidieser Methode schon nach der Übersetzung die Gewissheit, ob die Treiberklassegefunden wurde oder nicht.

���!%����()���'�������������������

JDBC unterstützt auch das automatische Laden von Treibern. Eine Liste von Treibern,getrennt durch Doppelpunkte, wird in der jdbc.drivers�Systemeigenschaft (Property)festgelegt, die vom Treibermanager beim Start automatisch geladen wird.

Tabelle 4.1 zeigt alle spezifischen Treiberklassen für die meist verwendeten Datenbank-systeme.

�������

Die Methode forName() wird gewöhnlich in einem separaten Block der Treiber-klasse aufgerufen, der beim Laden der Klasse ausgeführt wird und die Registrie-rung des Treibers durchführt.

Page 116: Java in Datenbanksystemen

��/ ������������� ��

*+���()��,�)�������%�-()�����.�������������/

Der erste Schritt – Treiber laden – ist zusammen mit der Herstellung der Verbindungzu einer Datenbank der kritischste Teil bei der Implementierung eines JDBC-Pro-gramms. Aus diesem Grund können unterschiedliche Fehler, die auf den ersten Blicknicht zu verstehen sind, auftreten. Im folgenden werden wir die häufigsten dieser Feh-ler auflisten und erläutern:

� falls der Benutzer statt Class class geschrieben hat, meldet JDBC bei der Überset-zung des Programms »illegal start of expression«

� wird der Treibername falsch geschrieben (Groß/Kleinschreibung ist wichtig!) oderist der Treiber nicht vorhanden (nicht im CLASSPATH), so gibt es beim Ausführendes Programms eine Ausnahme vom Typ ClassNotFoundException.

� beim Versuch, eine Verbindung herzustellen, nachdem der Treiber nicht geladenwurde, wird eine Instanz der Klasse SQLException mit der Fehlermeldung »Nosuitable driver«, dem ISO-Fehlercode 08001 und dem herstellerspezifischen Code 0ausgegeben.

���� ����� ��� ������ ������������� ����������������

� �0�� �1*���%�����2��(��������3��

2��(�����445)!���#!��4����%�6

7��782�3�8���2�3��"�#97��782�3�8�����%��"�#9

��$!�%�&�:��%�(�

-��3��

����� (!%���$!�%�&�2��(��$&��3��

2��(���$!�%�&��;���445���3������6�5#!��64

5����%�6��<,1=*�>-�=?�=@5���3����%�6

7�,>�78���8�$&2��(�2��97�,>�78���8�$&�;�2�2��9

1=��'� �A���0 !��(���2��(����3���

1��(����3��

2��(�!���

(����)���B5)!���#!������6

71=��'�78

(���������"�#971=��'�78���C()��������"�#9

��!��

�(�#�

�D�E�� �1*�(�!��

�(�#��(!��������3��

�1*�(�!����(�#��(!���=%����(

��3��

2��(�(�!���(�#��5��#��)6

2��(�(�!���(�#���%��445����3������6�5#!��645����%�6

7�'1F-����78

���8(������2��97�'1F-����78

$��%�G!� �8�%�2��(8(����

���8=%����(�2��9

-:����

-H'���:G�

)����4����#��3��

-��3��

�(!���(��

I

(!%��:�����2��(��

2��(�-:���3��

2��(��:���������5���3���

��%�6�5#!��645�����%��6

72�1<<���78

(������82(!����2��

*:-H' **�*:-H'���J�E

!����2��%%�%:�;����3��

2��(�%:�;��445���3������6�5#!��645����%�6

%%�%:�;��2��(�K3����!�L9

$������������0&�1���2��$�����+��������3����,�����������+�%��)�

Page 117: Java in Datenbanksystemen

������������������ �#'�(���))� ��4

����� ���M���������������?����������"���������������

Jeder JDBC-Treiber hat einen statischen Initialisierer, der beim Laden der Klasse aufge-rufen wird. Seine Aufgabe besteht darin, sich beim Treibermanager zu registrieren, umbei späteren Verbindungsanfragen von diesem angesprochen werden zu können.

Die wichtigste Klasse in Bezug auf die Datenbankverbindung ist die DriverManager-Klasse. Diese Klasse ist der Grunddienst für das Verwalten von JDBC-Treibern. Sieimplementiert den JDBC-Treibermanager, der einen oder mehrere JDBC-Treiber ver-waltet. Damit stellt die DriverManager-Klasse die Verwaltungsschnittstelle zwischenden Anwendungen einerseits und den Treibern andererseits dar.

Als Teil seiner Initialisierung versucht die DriverManager-Klasse, die Treiberklassen indie Jdbc.drivers-Systemeigenschaft zu laden. Dies erlaubt wiederum dem Benutzer,die von der Anwendung verwendeten JDBC-Treiber anzupassen.

Bei der Implementierung einer Java-Datenbankanwendung (oder eines Applets) ist dieURL (Uniform Resource Locator) der Datenbank die einzige treiberspezifische Informa-tion, die JDBC verlangt. (Ein URL ist ein eindeutiger Name, der das Auffinden einerRessource, in diesem Fall einer Datenbank, ermöglicht.) Mit Hilfe von URL, Kennungund Kennwort erstellt die Anwendung die Verbindung zu einer Datenbank. Dafürwird die Instanz der Connection-Schnittstelle verwendet. Eine Connection-Sitzungumfasst die SQL-Anweisungen, die durchgeführt werden und die Ergebnisse, die überdiese Verbindung zurückgegeben werden. Eine einzelne Anwendung kann eine odermehrere Verbindungen zu einer einzelnen Datenbank oder zu vielen unterschiedlichenDatenbanken haben.

Die wichtigsten Methoden der Klasse DriverManager sind in Tabelle 4.2 aufgelistetund beschrieben.

Die getConnection()-Methode ist mit Abstand die wichtigste Methode der KlasseDriverManager. Folgender Unterabschnitt ist dieser Methode gewidmet.

����!���(��!�NO �������������?����������"�������;�����P��������()�F='��� ���"��()��������

����������3��NO� ��%+���()����%�������������=�����������������"�����$������������%�������

���()"�$Q)����

������������3��NO� ,Q)�������������������������()�

�����3���NO '�����������������������������������$��

$���������"����2����5�2(��������6������������������

Page 118: Java in Datenbanksystemen

��� ������������� ��

�������!���(��!�NO�*��)!��

Die getConnection()-Methode erstellt die Verbindung zur Datenquelle, die durch URLgekennzeichnet ist. Beim Aufruf dieser Methode werden alle registrierten Treiber getes-tet, ob sie eine Verbindung zur Datenbank ermöglichen. Die Reihenfolge der getestetenTreiber ergibt sich aus der Reihenfolge ihrer Registrierung. (Diejenigen Treiber, die inder jdbc.drivers-Systemeigenschaft gespeichert sind, werden zuerst getestet.) Der ersteTreiber, der die gegebene URL erkennt, baut die Verbindung zur Datenquelle auf.

Die getConnection()-Methode hat drei verschiedene Ausprägungen:

������������������������������������������� �����������������������������������������0��������1������0��������1��������� �����������������������������������������0�2�������� ������

Die erste Variante übernimmt eine Zeichenkette, die die URL enthält. Die Standard-syntax für URLs bei JDBC sieht folgendermaßen aus:

!��34 �����������534!����5

subprotocoll kennzeichnet den Namen des Subprotokolls. (Das odbc-Subprotokollerlaubt die Angabe weiterer Parameter, die die Adresse der Ressource eindeutig identi-fizieren.) Neue Subprotokolle können unter

[email protected]

registriert werden. dbname spezifiziert den Datenbanknamen, der treiberabhängig ist.

Dementsprechend sieht die URL für eine Verbindung mit einer DB2-Datenbanknamens beispiel so aus:

����/�$!��3!�,3��� ����$�

Die zweite Ausprägung der getConnection()-Methode erlaubt es, zusätzlich zu URLden Benutzernamen und das Kennwort an das Datenbanksystem zu übergeben. Bei-spiel 4.3 zeigt diese Form der getConnection()-Methode.

Beispiel 4.3

������ ��������������������/�����������������/�$!��3!�,3��� ����$��������������� ���!�/������������$1������$���������������� �!�/������������$1�������$������������/�'�����+����������������������0�� ���!0�� �!��

Bei der dritten Ausprägung können treiberspezifische Infos mit Hilfe einer Instanz derKlasse Properties übergeben werden.

Bei der erfolgreichen Verbindung liefert getConnection eine Instanz, die die Connec-tion�Schnittstelle implementiert. Diese Instanz ist die Basis für die nachfolgendenSchritte.

Page 119: Java in Datenbanksystemen

������������������ �#'�(���))� ��!

����D ���������������-H'���G��������������)��-���������������������� �-��3��

Alle Abfragen und Datenmodifikationsanweisungen erfolgen mit Hilfe von so genann-ten Anweisungsobjekten. Ein Anweisungsobjekt ist eine SQL-Anweisungsfolge, diesich innerhalb einer Transaktion befindet. Anweisungsobjekte werden von der State-ment-Schnittstelle (oder einer ihrer Subkomponenten) implementiert und von Metho-den der Connection-Schnittstelle erzeugt.

Die Statement-Schnittstelle ist die Basisschnittstelle aller Klassen, die für die Erstel-lung der SQL-Anweisungen verwendet werden. In der Regel wird diese Schnittstellefür die Verarbeitung einfacher SQL-Anweisungen verwendet. Dabei benutzt sie dieMethode createStatement() der Connection-Schnittstelle.

Die PreparedStatement-Schnittstelle ist eine Unterklasse der Statement-Schnittstelle.Diese Schnittstelle wird gewöhnlich benutzt, um eine SQL-Anweisung, die zurÜbersetzungszeit noch nicht bekannt ist, auszuführen. Sie verwendet die prepareState-ment()-Methode der Connection-Schnittstelle, um SQL-Anweisungen vorzubereiten,womit eine effizientere Abarbeitung der Anweisungen möglich wird.

Die dritte Klasse – CallableStatement –, die zu derselben Hierarchie wie die beidenschon beschriebenen Schnittstellen Statement und PreparedStatement gehört, ist diedirekte Unterklasse der PreparedStatement-Schnittstelle. Sie wird benutzt, um denAufruf einer gespeicherten Prozedur (stored procedure) durchzuführen. Dabei verwen-det sie die prepareCall()-Methode der Connection-Schnittstelle.

Die Syntax der oben beschriebenen Methoden der Connection-Schnittstelle sieht fol-gendermaßen aus:

������������������������������ ��67"#��������2�����!�������������������������������� ��������� ��67"#���������������������������������� ������ ��������� ��67"#��������

Die Statement-Schnittstelle hat zahlreiche Methoden, von denen folgende drei für dieAusführung der SQL-Anweisungen verwendet werden:

� execute()

� executeQuery()

� executeUpdate().

�������

Instanzen der Klasse Statement sind im Allgemeinen kostspielige Ressourcen,deren Erstellung viel Speicherplatz kostet. Aus diesem Grund sollte die Erstellungeiner größeren Anzahl von solchen Instanzen vermieden werden.

Page 120: Java in Datenbanksystemen

�"� ������������� ��

Folgende Unterabschnitte beschreiben die drei oben genannten Methoden der State-ment-Schnittstelle.

����&�(���NO�*��)!��

Die Methode execute() führt eine SQL-Anweisung aus und liefert dabei einen Boole-schen Wert (true, false) zurück. Dieser Wert spezifiziert, ob es sich um eine Abfrage (derBoolesche Wert true) oder um eine andere SQL-Anweisung (der Boolesche Wert false)handelt. Diese Methode kann benutzt werden, um eine SQL-Anweisung auszuführen,die keine spezifische Ausgabe hat. Genauso kann sie benutzt werden, um zu ermitteln,ob es sich bei der SQL-Anweisung um eine Abfrage handelt, indem der Rückgabewertauf true getestet wird. Falls der Rückgabewert true ist, kann mit Hilfe der Methode get-MoreResults() der Statement-Schnittstelle die Ergebnismenge gelesen werden.

Das folgende Beispiel zeigt die Verwendung der execute()-Methode.

Beispiel 4.4

����/�'�����+������������������������ ����/��������������������� �����#������$�"*��899"�*���:"+;�!�, ����$��

In Beispiel 4.4 sind zuerst jeweils eine Instanz der Schnittstellen Connection und State-ment deklariert und initiiert worden, die für die Verbindung zum Datenbanksystemund die Erstellung der SQL-Anweisung notwendig sind. Mit der Anweisung

�����#������$�"*��899"�*���:"+;�!�, ����$��

wird eine SQL-Anweisung ausgeführt, die das Schema einer DB2-Datenbank festlegt.(Das Schema einer Datenbank ist ein SQL-Konstrukt, das in Bezug zu einem Benutzersteht, und alle Anweisungen zur Erstellung von Tabellen und Sichten sowie die Auto-risierungsanweisungen enthält.) Das Schema-Konstrukt wird von allen Datenbanksys-temen unterstützt, aber nur das DB2-Datenbanksystem von IBM verlangt die expliziteFestlegung des Schemanamens.

�������

Zusätzlich zu diesen drei Methoden existiert seit JDBC 2.0 auch die executeBatch()-Methode. Mit dieser Methode können mehrere Anweisungen als eine einheitlicheGruppe (batch) gemeinsam übersetzt und ausgeführt werden. Die Vorteile derBenutzung dieser Methode liegen im Performance-Bereich: Eine Gruppe derAnweisungen wird schneller übersetzt und ausgeführt als jede Anweisung separat.(Für weitere Erläuterungen bezüglich der executeBatch()-Methode siehe Kapitel 6.)

Page 121: Java in Datenbanksystemen

������������������ �#'�(���))� �"�

����&�(���H���:NO�*��)!��

Die executeQuery()-Methode führt eine SQL-Anweisung aus, die Reihen einer Tabelleausgibt. Damit steht diese Methode in Bezug zu Abfragen in einem Anwendungspro-gramm.

Die executeQuery()-Methode erwartet einen Parameter in Form einer gültigen SELECT-Anweisung und gibt eine Instanz vom Typ ResultSet zurück, die die Ergebnismengerepräsentiert. (Für die Beschreibung von ResultSet siehe den nächsten Abschnitt.) AlsArgument dürfen beliebige SELECT-Anweisungen übergeben werden, sofern sie fürdie zugrunde liegende Datenbank gültig sind.

Beispiel 4.5 zeigt die Verwendung der executeQuery()-Methode.

Beispiel 4.5

��������������������/������ �������������� ����������/�����������������������������������������������/�'�����+��������������������������������������������������������������������������/��$�"7"�*��<��0��<���0��<������� 9&+�����������=� ����������/���������������������9� �������� �/� �����������#�����6���-���������������������������������������������

In Beispiel 4.5 wird eine Zeichenkette, die eine SELECT-Anweisung enthält, derString-Variablen abfrage zugewiesen. Danach wird eine Instanz der Statement-Schnittstelle (stmtSelect) verwendet, um die angegebene SQL-Anweisung zu erstellen.Mit Hilfe der executeQuery()-Methode wird schließlich die Ergebnismenge einerResultSet-Variablen rs zugewiesen.

����&�(���F#����NO�*��)!��

Mit der executeUpdate()-Methode kann eine der SQL-Anweisungen zur Änderung derDatenbankinhalte (INSERT, UPDATE, DELETE) ausgeführt werden. Im Unterschied zuder executeQuery()-Methode, die die Ergebnismenge ausgibt, liefert executeUpdate()die Anzahl der Reihen, die durch INSERT, UPDATE oder DELETE geändert wurden.

Beispiel 4.6 zeigt die Verwendung der executeUpdate()-Methode.

Beispiel 4.6

������������������������������������������� �/�������������������������!�����<>������/���� ��#�����8�!���$'"7"*"� 9&+���������?:"9"���<���/�@�.@$������������������������������������������������������������

Page 122: Java in Datenbanksystemen

�"" ������������� ��

Beispiel 4.6 zeigt die Ausführung einer DELETE-Anweisung. Das Ergebnis dieserAnweisung ist eine Ganzzahl, die die Anzahl der gelöschten Reihen spezifiziert. ImBeispiel wird dieser Wert als Rückgabewert der executeUpdate()-Methode an dieVariable delete_zaehler zugewiesen. Für ein weiteres Beispiel zu executeUpdate()siehe Beispiel 4.13.

����� =��)��G�����?�����������

Eine Instanz der Schnittstelle ResultSet stellt die Ergebnismenge einer Abfrage darund ermöglicht damit den Zugang zu Daten einer Datenbank. Eine der wichtigstenMethoden der ResultSet-Schnittstelle ist die Methode next��, mit der die Ergebnis-menge schrittweise abgearbeitet werden kann. Der Rückgabewert dieser Methode istvom Typ boolean: Abhängig davon, ob die nächste Reihe in der Ergebnismenge exis-tiert oder nicht, wird der Wert richtig (true) oder falsch (false) sein.

Nach dem Aufruf der executeQuery()-Methode ist der Zeiger, der auf die Reihen derErgebnismenge positioniert wird, vor der ersten Reihe der Ergebnismenge platziert.Der erste Aufruf der Methode next() bewegt den Zeiger zur ersten Reihe. Der Rückga-bewert gibt an, ob die Operation erfolgreich war. Danach kann der Zeiger mit Hilfederselben Methode und einer Schleife sequenziell auf die weiteren Reihen der Ergeb-nismenge positioniert werden.

Beispiel 4.7 zeigt die Verwendung der ResultSet-Schnittstelle für die Abarbeitung derErgebnismenge einer Abfrage.

Beispiel 4.7

��������� ����/����������������������9� �������� ���/� �����#�����6����-��A�"7"�*��� 9&+�����������B������������� �����#������C����������((D�������������>�����9������!���"������ ������������������������������E

In Beispiel 4.7 wird mit Hilfe der executeQuery()-Methode eine Abfrage auf dieTabelle mitarbeiter ausgeführt. Die Ergebnismenge dieser Abfrage wird mit Hilfeeiner while-Schleife sequenziell abgearbeitet. Nach der Abarbeitung der ersten Reihewird, falls weitere Reihen in der Ergebnismenge existieren, der Rückgabewert derMethode auf true gesetzt und die while-Schleife wieder ausgeführt. Wenn die Ergeb-nismenge keine weiteren Reihen enthält, wird der Rückgabewert auf false gesetzt unddamit die while-Schleife beendet.

�������

Der Zeiger, der auf die Reihen der Ergebnismenge zeigt, heißt Cursor.

Page 123: Java in Datenbanksystemen

������������������ �#'�(���))� �"*

Der Wert einer Spalte, der zurückgegeben wird, kann auch NULL sein. (Ein NULL-Wert ist ein spezieller Wert, der verwendet wird, wenn die Information für einen Spal-tenwert fehlt oder nicht bekannt ist (siehe auch Kapitel 1).) In diesem Fall muss dieSpalte gelesen und auf den NULL-Wert überprüft werden.

Mit der Methode wasNull() der ResultSet-Schnittstelle ist es möglich, zu überprüfen,ob ein Spaltenwert dem NULL-Wert gleich ist. Der Rückgabewert der Methode istboolean; damit wird true zurückgegeben, falls der Spaltenwert NULL ist, und false inallen anderen Fällen.

����I =�����-�����G����������

Die im letzten Abschnitt beschriebene reihenweise Abarbeitung der Ergebnismenge istsehr eingeschränkt, weil sie die Reihen immer sequenziell durchläuft und die Ergeb-nismenge nur statisch sein kann. Sequenziell heißt, dass der Cursor mit der Methodenext() immer nur die nächste Reihe einer Ergebnismenge abarbeiten kann. Die stati-sche Ergebnismenge bedeutet, dass diese Menge einmal (am Anfang) festgelegt wirdund alle anschließenden Änderungen keinen Einfluss auf den Inhalt der Ergebnis-menge haben.

Mit JDBC API 2.0 wurden signifikante Änderungen in Bezug auf die Abarbeitung derErgebnismenge eingeführt. Diese Version hat folgende Erweiterungen:

� Scroll-Cursor

� sensitive Ergebnismengen

� veränderbare Ergebnismengen.

Um diese Erweiterungen zu implementieren, wurden einige Klassen des java.sql-Pakets geändert. Die erste Änderung betrifft die createStatement()-Methode der Con-nection-Schnittstelle. Diese Methode wurde überladen, so dass jetzt neben der Basis-form ohne Parameter eine Form mit zwei Parametern existiert. Diese beiden Parameterstehen direkt im Zusammenhang mit der Erstellung unterschiedlicher Ergebnismen-gen.

Die allgemeine Form der createStatement()-Methode mit zwei Parametern sieht fol-gendermaßen aus:

�������������������� ������*-��0��� ����������������-�

�������

Die Methode wasNull() wird erst aufgerufen, nachdem der Spaltenwert mit Hilfeeiner der Methoden getXXX() gelesen wird.

Page 124: Java in Datenbanksystemen

�"� ������������� ��

wobei resultSetType den Typ der Ergebnismenge (result set type) und resultSetConcur-rency den Zugriffstyp auf die Ergebnismenge (result set concurrency) festlegt.

Die beiden anderen Methoden der Schnittstelle Connection – prepareStatement() undprepareCall() – sind, entsprechend der Methode createStatement(), überladen wor-den, um Instanzen der Klassen PreparedStatement bzw. CallableStatement (in derReihenfolge) mit dem entsprechenden Typ der Ergebnismenge und dem Zugriffstypauf die Ergebnismenge zu erweitern.

� Die Syntax dieser beiden Methoden mit den beiden Parametern sieht folgender-maßen aus:

2�����!�������������������������������� ��0������� ������*-��0������� ����������������-������� ��67"#����������������������������������������� ��0������� ������*-��0������� ����������������-������� ��67"#��������

Der Typ der Ergebnismenge (result set type) kann dreierlei sein:

� vorwärts (forward-only)

� scroll-insensitiv

� scroll-sensitiv

während der Zugriffstyp (result set concurrency) zwei Formen hat:

� Änderungen nicht möglich (read-only)

� Änderungen möglich (updatable).

Dementsprechend können folgende Konstanten, die in der Klasse ResultSet definiertsind, als Werte für den Parameter resultSetType in den Methoden createStatement(),prepareStatement() und prepareCall() verwendet werden:

� static int TYPE_FORWARD_ONLY

� static int TYPE_SCROLL_INSENSITIVE

� static int TYPE_SCROLL_SENSITIVE

Für den Parameter resultSetConcurrency können zwei Werte:

� static int CONCUR_READ_ONLY

� static int CONCUR_UPDATABLE

benutzt werden.

Der Wert TYPE_FORWARD_ONLY ist der einzige Parameter, der einen Nicht-Scroll-Cursor definiert. Die anderen beiden Konstanten in Bezug auf den Typ der Ergebnis-menge definieren, ob die Änderungen der Ergebnismenge erlaubt sind oder nicht.

Page 125: Java in Datenbanksystemen

������������������ �#'�(���))� �".

Die Konstante TYPE_SCROLL_SENSITIVE spezifiziert einen sensitiven Cursor. Einsolcher Cursor erlaubt dem Benutzer, die Änderungen an den Reihen der Ergebnis-menge zu sehen, falls er während der Abarbeitung der Reihen zu einer früher gelese-nen Reihe zurückkehrt. Dementsprechend kennzeichnet die Konstante TYPE_SCROLL_INSENSITIVE, dass die Ergebnismenge festgelegt und keine anschließendeÄnderung dieser Reihen für den Benutzer sichtbar ist.

Der Wert CONCUR_READ_ONLY definiert, dass die Ergebnismenge nur gelesen wer-den kann, während CONCUR_UPDATEABLE eine positionierte Änderung der Reihender Ergebnismenge ermöglicht. (Für alle solchen Werte werden später in diesem Kapi-tel Beispiele gezeigt. Beispiel 4.17 zeigt die Verwendung eines Scroll-Cursors, währendBeispiel 4.18 eine positionierte Änderung demonstriert.)

Nach der Erstellung einer Ergebnismenge (d.h. eine Instanz der ResultSet-Schnittstelle)wird der dazugehörige Cursor vor der ersten Reihe positioniert. Jede Ausführung dernext()-Methode positioniert den Cursor auf die nächste Reihe der Ergebnismenge.

Bei einem Scroll-Cursor können einzelne Reihen, die mit der SELECT-Anweisung aus-gewählt wurden, nicht nur sequenziell, sondern auch in beliebiger Reihenfolge ange-sprochen werden. Dementsprechend unterstützt die ResultSet-Schnittstelle neben dernext()-Methode auch folgende Methoden:

� ���!������� �� ��������� ��67"#��������

� ���!�����7 ��������� ��67"#��������

� �������� ������������������� ��67"#��������

� ���������������������������� ��67"#��������

� �������������� �������� ��67"#��������

� ���!���� ���������� ��67"#��������

� ���!�� ���������� ��67"#��������

Die Methode beforeFirst() positioniert den Cursor vor der ersten Reihe der Ergebnis-menge, während afterLast() den Cursor nach der letzten Reihe der Ergebnismengesetzt.

Die Methode absolute( ) positioniert den Cursor auf die Reihe m der Ergebnismenge(m ist der ganzzahlige Parameter dieser Methode). Der Rückgabewert dieser Methodekann richtig (falls der Cursor innerhalb der Ergebnismenge positioniert wird) oderfalsch sein (falls der Cursor außerhalb der Ergebnismenge positioniert wird).

Der Wert des Ganzzahlparameters m kann positiv und negativ sein. Ein negativer Wertspezifiziert die Positionierung rückwärts ab der letzten Reihe der Ergebnismenge,während ein positiver Wert die Positionierung vorwärts ab der ersten Reihe festlegt.(Damit ist die Wirkung dieser Methode mit dem Rückgabewert false identisch mit der

Page 126: Java in Datenbanksystemen

�"/ ������������� ��

Ausführung der Methode afterLast(), falls der Parameter positiv ist bzw. identisch mitder Methode beforeFirst(), falls der Parameter negativ ist.)

Die Methode relative() verschiebt den Cursor um n Reihen von der aktuellen Reihenach unten oder oben (abhängig davon, ob der ganzzahlige Parameter n positiv odernegativ ist). Genauso wie bei der absolute()-Methode wird der Rückgabewert richtigoder falsch sein, abhängig davon, ob der Cursor innerhalb oder außerhalb der Ergeb-nismenge positioniert wird.

Die Methode previous() positioniert den Cursor auf die vorherige Reihe der Ergebnis-menge. Falls der Cursor vor der Ausführung der previous()-Methode auf die ersteReihe zeigte, wird als Rückgabewert false zurückgegeben. Die Methoden first() undlast() bewegen den Cursor zu der ersten Reihe bzw. zu der letzten Reihe der Ergebnis-menge.

Neben den oben genannten Methoden enthält die ResultSet-Klasse auch eine andereGruppe von Methoden, die in Bezug zu der gegenwärtigen Position des Cursors ste-hen. Zu diesen Methoden gehören:

� �������� �� ��������� ��67"#��������

� �������� 7 ��������� ��67"#��������

� �������� )����� �� ��������� ��67"#��������

� �������� ;����7 ��������� ��67"#��������

� �������9���������� ��67"#��������

Die Funktionalität aller dieser Methoden kann aus ihren Namen herausgelesen wer-den. Die Methode getRow() gibt eine Ganzzahl zurück, die die Position der aktuellenReihe der Ergebnismenge spezifiziert.

Die Methoden setFetchDirection() und setFetchSize() können die Performance derAnwendung beeinflussen, falls der verwendete Treiber ihre Funktionalität unterstützt.Die Methode setFetchDirection() ermöglicht dem Benutzer, dem Treiber im vorausmitzuteilen, in welcher Richtung die Ergebnismenge abgearbeitet wird. Der WertResultSet.FETCH_FORWARD spezifiziert die übliche Abarbeitung der Reihen vonAnfang an, während der Wert ResultSet.FETCH_REVERSE dem Treiber die gegensätz-liche Richtung der Abarbeitung signalisiert. Falls die Reihen weder ausschließlich ineiner noch ausschließlich in der anderen Richtung abgearbeitet werden, kann der WertResultSet.FETCH_UNKNOWN verwendet werden.

�������

Ob die explizite Angabe der Abarbeitungsrichtung überhaupt einen Performance-Gewinn bringt, hängt ausschließlich von dem verwendeten Treiber ab. MancheTreiber unterstützen diese Methode und manche eben nicht.

Page 127: Java in Datenbanksystemen

������������������ �#'�(���))� �"4

Mit der Methode setFetchSize() kann dem Treiber die Anzahl der Anfangsreihen einerErgebnismenge, die im Programm benutzt werden, mitgeteilt werden. Falls die Ergeb-nismenge viele Reihen enthält, und Sie an den wenigen Anfangsreihen interessiertsind, kann die Verwendung dieser Methode signifikante Performance-Vorteile bringen.(Der Standardwert 0 besagt, dass keine explizite Angabe gemacht wird und alle Reihender Ergebnismenge für den Benutzer relevant sind.)

����E �������������������������

Die ResultSet-Schnittstelle unterstützt eine Reihe von Methoden, die alle in Bezug zuder Ausgabe der Reihenwerte einer Ergebnismenge stehen. getXXX ist der generischeName für alle Methoden der ResultSet-Schnittstelle, die einzelne Spaltenwerte deraktuellen Reihe holen. Dementsprechend existieren viele Methoden, die den angegebe-nen Spaltenwert auf Grund des Datentyps der Spalte umwandeln. Mit anderen Wortenversucht ein JDBC-Treiber für die getXXX()-Methoden die zugrunde liegenden Datenin den angegebenen Java-Typ umzuwandeln und gibt einen passenden Java-Wertzurück.

Dementsprechend wird die getInt()-Methode verwendet, um einen Spaltenwert in denJava-Typ int umzuwandeln, während die getDate()-Methode den entsprechendenSpaltenwert in Java-Typ date konvertiert.

Eine besondere Rolle spielen die zwei getXXX()-Methoden:

� �����������

� ���&�������

Alle alphanumerischen SQL-Datentypen werden auf den Java-Datentyp String abge-bildet. Dementsprechend unterstützt JDBC für alle alphanumerischen Datentypen dieMethode namens getString().

Die getObject()-Methode konvertiert alle Spaltenwerte zu einer Instanz vom TypObject. Weil Object bei Java die Klasse aller Klassen darstellt, kann jeder SQL-Daten-typ mit dieser Methode bearbeitet werden (siehe Beispiel 4.17).

Beispiel 4.8 zeigt den Ausschnitt eines JDBC-Programms, das das Resultat einer Ergeb-nismenge ausgibt.

�������

Die beiden Methoden setFetchDirection() und setFetchSize() werden noch inKapitel 6 erörtert.

Page 128: Java in Datenbanksystemen

�"� ������������� ��

Beispiel 4.8

�����9� �������� �/���������������������������������������������������� / �����#�����6���-�$�"7"�*��<��0�<���0�<������� 9&+����������$���������� ���#�����C������������������/�� �����������F���((������/������F��!���9�������������������/� �����������,����((����/�������,��!���9���������������������/� �����������G���((�������/�������G��!���9����E

In Beispiel 4.8 wird eine Ergebnismenge erstellt und diese der Variablen rs zugewiesen.Mit Hilfe der next()-Methode wird die Ergebnismenge reihenweise abgearbeitet.Schließlich werden mit Hilfe der getString()-Methode die Spaltenwerte der aktuellenReihe der Variablen nummer, name und vorname (in dieser Reihenfolge) zugewiesen.

Die Nummern und Eigenschaften von Spalten einer Ergebnismenge können aus demSystemkatalog abgefragt werden. (Die Klassen und Methoden bezüglich des System-katalogs sind später in diesem Kapitel beschrieben.)

����0 -()���R�������?����������"�%�������� �-��3��

Das explizite Schließen von Instanzen wird mit der Methode close() durchgeführt. DieAnwendung dieser Methode ist optional: Spätestens mit dem Aufruf des Garbage Col-lectors werden alle nicht mehr referenzierten Objekte geschlossen.

Folgende Klassen enthalten die Methode close():

� Connection

� Statement

� ResultSet.

Beim Schließen einer Instanz der Statement-Schnittstelle wird auch die zugehörigeInstanz der Resultset-Schnittstelle implizit geschlossen. Entsprechendes gilt beimSchließen der Datenbankverbindung: Nicht nur das Connection-Objekt wird geschlos-

�������

Die Spaltenwerte können entweder mit Hilfe der Indexnummer oder des Namens derSpalte ermittelt werden. In Beispiel 4.8 wurde die Indexnummer der Spalte verwen-det, um die Spaltenwerte der aktuellen Reihe an die String-Variablen zuzuweisen.

�������

Spaltennamen, die als Parameter der getXXX()-Methoden verwendet werden, sindcase insensitive, weil es sich um SQL-Namen handelt.

Page 129: Java in Datenbanksystemen

����0�2�3����,(�� 0��' �"!

sen, sondern auch das entsprechende Statement- und das Resultset-Objekt. Prinzipiellsollten diese Instanzen immer geschlossen werden, sobald sie nicht mehr benötigt wer-den.

��D ���-()�Q����G!����-����

ESCAPE ermöglicht bessere Portierung von JDBC-Anwendungen. Dieses Schlüssel-wort verwendet gewisse Angaben, die besondere Zeichenfolgen erkennen und diesedann in das spezifische Format bzw. die spezifische Form eines Datenbanksystemstransformieren.

Der Ursprung dieses Schlüsselwortes ist SQL, wo die ESCAPE-Angabe für die Spezifi-kation des Entwertungszeichens im LIKE-Operator verwendet wird:

���������#����6���-��A�"7"�*���<��0���<���� 9&+�����1����������������������������?:"9"���<����7HI"�@JK<K@�"��;2"�@K@B��

In der obigen SELECT-Anweisung wird die ursprüngliche Bedeutung des Zeichens»_« wiederhergestellt, indem diesem Zeichen das Entwertungszeichen »!« vorange-stellt wird. (Das Sonderzeichen »%« kennzeichnet eine beliebige Zeichenfolge von nZeichen, wobei n eine nichtnegative Ganzzahl ist, während das Sonderzeichen »_«genau ein beliebiges Zeichen spezifiziert.)

Das ESCAPE-Schlüsselwort kann mit der setEscapeProcessing()-Methode der KlasseStatement ein- und ausgeschaltet werden. (Der Standardwert ist eingeschaltet.) DieSyntax von ESCAPE sieht folgendermaßen aus:

C�������������� ��E

angabe kennzeichnet den Angabennamen, während parameterliste ein oder mehrereArgumente der entsprechenden Angabe enthält.

ESCAPE wird meistens in den Fällen angewendet, wo jedes Datenbanksystem spezifi-sche Angaben enthält. Zwei solche Bereiche sind u.a. skalare Funktionen und Datums-formate. Bei den skalaren Funktionen verwendet jedes Datenbanksystem spezifischeNamen. Das hat auch damit zu tun, dass der SQL-Standard, abgesehen von einigenwenigen Funktionen (wie USER, CURRENT_USER, SYSTEM_USER undSESSION_USER), keine Vereinheitlichung in diesem Bereich vorgesehen hat. (Die Listealler mathematischen und alphanumerischen skalaren Funktionen kann mit Hilfe derMethoden getNumericFunctions() und getStringFunctions() der Klasse DatabaseMe-taData in dieser Reihenfolge ermittelt werden.)

Die Angabe fn spezifiziert eine skalare Funktion:

C����������$'�����1$0�$;����!���$��EC���� �����E

Page 130: Java in Datenbanksystemen

�*� ������������� ��

Die erste Angabe teilt mit, dass es um die Konkatenierung zweier Zeichenketten geht.Die Angabe concat wird damit von dem eingesetzten Treiber durch den Konkatena-tionsoperator des Zielsystems ersetzt. Im zweiten Beispiel wird die SystemfunktionUSER() verwendet, um den Namen des aktuellen Benutzers zu ermitteln.

Genauso kann ein Datumswert mit Hilfe der Angabe d umgewandelt werden:

C!�L,MMF�F,�MNL�E

Die d-Angabe erwartet als Argument eine Zeichenkette im Format ’jjjj-mm-dd’. DerTreiber macht daraus den spezifischen Datumswert des Zieldatenbanksystems. Wei-tere Datumsangaben sind t und ts, die für die Zeitangabe bzw. Zeitstempel (timestamp)in dieser Reihenfolge verwendet werden.

��� �����������,�)�����)�������

Die Fehlerbehandlung für JDBC basiert auf den Ausnahmen der Sprache Java. Grund-sätzlich melden die meisten Methoden der JDBC-Klassen einen Fehler durch eine Aus-nahme der Klasse SQLException. Diese Klasse ist eine Unterklasse der KlasseException und damit auch die Unterklasse von Throwable.

����� ����������-H'�&(�#��!�

Die Information, die die SQLException-Klasse liefert, enthält:

� Fehlermeldungstext

� Fehler-Code

� eine Kette von Ausnahmen.

Der Fehlermeldungstext beschreibt den aufgetreteten Fehler. Eine Anwendung, dieden Fehlermeldungstext benutzt, greift auf diesen String-Wert mit Hilfe der getMes-sage()-Methode der Klasse Throwable zu. Der Fehler-Code kann entweder hersteller-spezifisch sein oder dem XOPEN-Standard entsprechen. Dementsprechend existierenzwei unterschiedliche Methoden der Klasse SQLException, die beide eine Ganzzahlals Rückgabewert liefern (siehe Tabelle 4.2).

In Bezug auf die Serie von Ausnahmen bekommt die Anwendung die erste Instanz derKlasse SQLException zugestellt. Die Methode getNextException() dieser Klasse liefertdie nächste Ausnahme. Falls die nächste Ausnahme nicht existiert, wird der NULL-Wert zurückgegeben.

Tabelle 4.3 listet die wichtigsten Methoden der Klasse SQLException auf.

Page 131: Java in Datenbanksystemen

�� ���������7�2�����2������� �*�

Folgendes Beispiel zeigt einen try/catch-Block, in dem die Methoden der KlasseSQLException verwendet werden.

Beispiel 4.9

��-�C���������((�;����������%')�� ��1������E��������67"#������������C�����- ����������������$O������67"#�����������������������O�$������!�C���������- ����������������$ ��������!����3�����$�P������+� ���������������- ����������������$Q&2"�� �������!��3��$�P������67�����������������- ����������������$:�� ���������!��3���$�P������"������!������������������������������P�$O�$������E������������/��������#�"#�����������K/�������E

Im try-Block des Beispiels 4.9 können eine oder mehrere SQL-Anweisungen angege-ben werden. Falls Fehler auftreten, wird die Instanz e der Klasse SQLExceptionerstellt, die den XOPEN- und herstellerspezifischen Fehler-Code sowie den Text derFehlermeldung ausgibt. Mit Hilfe der Methode getNextException() wird anschließenddie nächste Ausnahme (falls existent) geholt und dieselbe Information ausgegeben.

����� ����������-H' ������

Die Klasse SQLWarning ist eine Unterklasse der Klasse SQLException, die für alleWarnungen zuständig ist. Die wichtigsten Methoden in Bezug auf diese Klasse sind:

� getWarnings()

� clearWarnings().

Die erste Methode liefert eine Instanz der Klasse SQLWarning, die dann verwendetwerden kann, um Warnungen im Zusammenhang mit den anderen Klassen abzufan-gen. Das heißt, dass die folgende Instanz der Klasse SQLWarning:

��������������?����� ��

Warnungen von Methoden enthält, die in Bezug zu der Connection-Schnittstelle ste-hen. Genauso beinhaltet:

������!��!��NO '��$��������)����������#�"�$��()���,�)�����!���

���<�&��&(�#��!�NO '��$���������S()���������)%��

���-H'-����NO '��$����>1��<�-H'-�����,�)�����!���

���<�&��&(�#��!�

�����N-H'�&(�#��!���&O

F������Q�"�������)%�3�� ��������N��������$��$�)!��������S()����

�����)%����������'�����O

$���������*�����,�2�����5�2(��������-H'�&(�#��!�#6�����

Page 132: Java in Datenbanksystemen

�*" ������������� ��

9� ����������?����� ��

ausschließlich Warnungen, die von den Methoden der ResultSet-Schnittstelle erzeugtwerden. Schließlich beinhaltet die Instanz

������������?����� ��

ausschließlich Warnungen, die von den Methoden der Klasse Statement erzeugt wer-den. Die Eigenschaft dieser Warnungen ist, dass sie automatisch bei der Ausführungeiner der execute()-Methoden gelöscht werden. (Die Methode getWarnings() ist auchin den anderen beiden Klassen CallableStatement und PreparedStatement enthalten.)

Die zweite Methode – clearWarnings() – entfernt alle Warnungen.

Beispiel 4.10 zeigt die Verwendung der SQLWarning-Klasse.

Beispiel 4.10

����������������������������������������������� ��������!� ���?����� ��67?�������������� ��67"#�����������C������������//����������������������- ����������������$O�����?�������3����O�$����������������/�F���������!�C�������������- ����������������$?������R$�P���PP��P�$3$���������������- ����������������$Q&2"�� �������!�3�$�P��������������������������������������67���������������������- ����������������$ ��������!���3����$�P�������������������������������������+� �������������������- ����������������$:�� ���������!�3��$�P�������������������������������������"������!�������������E������������/��������#�?���������K/�����������EE

Beispiel 4.10 zeigt den Ausschnitt aus einem JDBC-Programm, wo die Klasse SQL-Warning mit ihren Methoden getSQLState(), getMessage() und getErrorCode() ver-wendet wird. Diese Methoden sind die geerbten Methoden der Klasse SQLException,die wir schon vorher erläutert haben. (Die Warnungen werden in einer Kette gespei-chert, damit sie dann mit Hilfe der Methode getNextWarning() sequenziell gelesenwerden können.)

��I T������"�����������$Q)����������������!���%%�

Die Voraussetzung für die Übersetzung eines JDBC-Programms ist, dass das Quellpro-gramm die Endung ».java« enthält, und der Name des Programms mit dem Namender Klasse, die das main-Programm beinhaltet, übereinstimmt.

Page 133: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �**

Die Übersetzung und die Ausführung eines JDBC-Programms läuft genauso wie dieÜbersetzung eines Java-Programms ab (siehe den entsprechenden Abschnitt in Kapitel3). Der einzige Unterschied ist, dass die entsprechenden Pakete des jeweiligen Daten-banksystems im CLASSPATH eingetragen werden müssen. (Die Namen der Pakete fürjedes spezifische Datenbanksystem können Sie in Spalte »CLASSPATH Pakete« inTabelle 4.1 finden.)

��E U���T������"����"����$!�%��������-H'���G��������

Die Klasse Statement� ist die Basisklasse, die die Verarbeitung einfacher SQL-Anwei-sungen erlaubt. Mit den Methoden dieser Klasse:

� executeQuery()

� executeUpdate()

� execute()

können SQL-Anweisungen zur Übersetzungszeit formuliert werden. Alle SQL-Anwei-sungen können in drei Gruppen unterteilt werden, abhängig davon, ob sie eineAbfrage, eine DML-Anweisung (außer Abfrage) oder irgendeine andere Anweisungdarstellen. Falls eine Anweisung eine Ergebnismenge liefert, wird sie mit Hilfe der exe-cuteQuery()-Methode abgearbeitet. Genauso werden die anderen drei DML-Anwei-sungen (INSERT, UPDATE und DELETE) mit Hilfe der executeUpdate()-Methodeübersetzt und ausgeführt. Schließlich wird die execute()-Methode für alle anderenSQL-Anweisungen verwendet.

Das folgende Beispiel zeigt ein JDBC-Programm, das eine Datendefinitionsanweisung(CREATE TABLE), die zur Übersetzungszeit bekannt ist, übersetzt und ausführt.

Beispiel 4.11

��������� ������������8��� ����� ������'���C���� ��������������')+��/�')8��� �&9;�7"�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//��������������

ORACLE, INFORMIX, DB2, MySQL

Page 134: Java in Datenbanksystemen

�*� ������������� ��

����������-��������C�������������- ����������������$T�����!����>��')�&IO�*��������������������������������������� ���������$��������������((��������������������3������������ ����/���������������������������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*�������������������������������������������:"+;�!�,!���$��������������(( ��� �����67�'+7�;���� ����� �U���������������� �����#������$�9";*"�*;)7"��� ���������F�����.����������0�������,������������������,M����������0�������G�����FZ���$���������������- ����������������$*������*"�*��� �����$�������������� �����#������$'9&2�*;)7"�*"�*$���������������- ����������������$*������*"�*����S ���$��������������((;� ���� ���������������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3����������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe ist:

T�����!����>��')�&I*�������� ���������*������*"�*��� �����*������*"�*����S ���

In Beispiel 4.11 wird mit Hilfe der CREATE TABLE-Anweisung eine Tabelle namenstest erstellt. Im ersten Teil des Programms werden alle notwendigen Instanzen derSchnittstellen Connection und Statement, sowie die String-Variable url für die Spei-cherung von URL erstellt.

Die beiden Programmzeilen in Beispiel 4.11

����K')8��� �����'�� �'������')+��������������������/�')8��� ��������'�) ��')+����//��������������

dienen dazu, um eine Verbindung mit der Datenbank aufzubauen. Dazu wird einevorher definierte Konstante übergeben. Die erste Anweisung lädt und initialisiert den

Page 135: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �*.

Datenbanktreiber, während die zweite die Verbindung zur Datenbank herstellt undeine Instanz der Connection-Schnittstelle liefert. Diese beiden Hilfsfunktionen werdenin allen Beispielen verwendet und dort nicht mehr explizit erklärt. (Nähere Informa-tionen zur DBUtils-Klasse finden Sie im nächsten Beispiel.)

Mit Hilfe der createStatement()-Methode wird eine Instanz der Klasse Statementerstellt, die der Variablen stmt zugewiesen und für das Senden der SQL-Anweisungzum Datenbanksystem benutzt wird. Schließlich wird mit Hilfe der execute()-Methodedie CREATE TABLE-Anweisung ausgeführt.

Alle Anweisungen des JDBC-Programms befinden sich in einem try-Block. Das Abfan-gen der möglichen Fehler wird mit zwei verschiedenen catch-Blöcken durchgeführt:Der erste Block fängt Ausnahmen mit Hilfe der Klasse SQLException ab, während derzweite für das Abfangen allgemeinerer Ausnahmen mit Hilfe der Klasse Exceptiondient.

Wie wir schon erläutert haben, können die in diesem Buch aufgelisteteten Beispiele mitfolgenden Datenbanksystemen benutzt werden:

� Oracle

� MySQL

� IBM DB2

� Informix.

Um Programme des Buches mit allen oben genannten Datenbanksystemen verwendenzu können, haben wir ein JDBC-Dienstprogramm namens DBUtils als separate Klasseimplementiert, um die Zugriffe zu den verschiedenen Datenbanksystemen zu ermögli-chen. Die entsprechende Programmzeile in Beispiel 4.11

��� ��������������')+��/�')8��� �&9;�7"�

definiert Oracle als das für dieses Beispiel verwendete Datenbanksystem. (Neben derVariablen DB2, MYSQL und INFORMIX, mit denen die Zieldatenbanksysteme IBMDB2, MySQL und Informix (in dieser Reihenfolge) gewählt werden können, unter-stützt das Dienstprogramm auch die Verbindung zu dem JDBC-ODBC-Treiber derFirma SUN sowie zu den Java Datenbanksystemen Pointbase und Cloudscape.)

������������ ������� ���� ���������

Wie aus dem Beispiel 4.11 ersichtlich, verlangt DB2 die Angabe der SET CURRENTSCHEMA-Anweisung, mit der das entsprechende Schema, zu dem die im Programmangesprochenen Datenbankobjekte (Tabellen, Sichten) gehören, festgelegt wird. Der imProgramm verwendete Name (db2admin) muss durch den spezifischen Schemana-men Ihres DB2-Systems ersetzt werden.

Page 136: Java in Datenbanksystemen

�*/ ������������� ��

Für unsere Beispiele werden wir immer gleiche Abschnitte zum Aufbau der Verbin-dung, zur Fehlerabfrage oder zu Hilfsfunktionen benötigen. Diese Funktionen sind inder Klasse DBUtils zusammengefasst. Auch verringert sich so der Umfang der hierabgedruckten Beispiele auf die Wesentlichen Kernbestandteile.

Beispiel 4.12 zeigt das Dienstprogramm mit der Hilfsklasse DBUtils.

Beispiel 4.12

��1���8��� ���������� ����������������������������((8�����-�I� ���U��'�����1�D�������((���!��U��!���)�� ���������S����0����!�����8�����������>�� �������((!���I����������U ������ �������!���X�!�������!����������� �')8��� �C����(( ��� ����'��������� �>���')+��?������ ���������������������%')�&')��/�M����� ���������������������&9;�7"�/�F����� ���������������������'),�/�,����� ���������������������H� &9+HQ�/�G����� ����������������������7&8'��;2"�/�.����� ���������������������2&H�*);�"�/�Z����� ���������������������+[�67�/�\�����((��������������������������������������� ��������������'9HT"9H'Q/M����� ��������������897H'Q/F����� ��������������8�"9H'Q/,����� ��������������2;��?&9'H'Q/G�����((I����������� �;��-0�����X���4'�����504897504� ��504� ���!5���� �����������VWVW�!�����/C������������(( U��!���%')��&')��)��!����� �!������ �������!��')�������������((&')��*��������� ����������!�!���)����>����>����- ����������������(('������!����- ��� ���������1������������ ���������������((�&9;�7"3������������C$ ���!����!���%!��&!��'�����$0�$!��3�!��3 ����$0$!�,!���$0��������������$!�,!���$E0((&')�������������C$������!���!������&����'�����$0�$!��3�����3����3��������������]F.F�\M�F,M�F.N3FZ,F3�����MF$0$ ����$0$�����$E0������������((�'),3������������C$�&+�����!�,�!�������'),'�����$0�$!��3!�,3((F.F�\M�F,M���������������FG^3FZZZ( ����$0$!�,!���$0$!�,!���$E0������������(('),�*-�.�*����������������!�, ����4������5�� �U����������������((�H� &9+HQ3������������C$�����������#�!���H�#'�����$0$!��3�������#� ���3((F.F�\M�F,M���������������F.N3FZ,\(��� ����3H� &9+HQ�"9T"9/��<�������#$0$�������#$0��������������$�������#$E0������������((����! ���3

ORACLE, INFORMIX, DB2, MySQL

Page 137: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �*4

������������C$�&+�����! ���������%')�'�����$0�$!��3����! ���3�;+27"��������������������/����$0$$0$$E0������������((2����� �3������������C$���������� ��!���!��8����� �'�����$0$!��3������ �3 �����3((�������������������� �( ����0���$0$������$0$������$E0������������((+[�67������������C$�����������- ���'�����$0$!��3�- ��3((������ �( ����_� ��/����`��������������� ���!/$0$$0$$E����E������������ ����������������'�� �'����������!�� ��C����������-��������C������������((����:�����!� �'�����+���� �!���*����������� ��������������������� ��������!�����V!�� �WV'9HT"9H'QW����������������������������������E��������(( ���������!�����Y�!���*���������� ���������� ��1���� ���������������"#������������������C�������������- ����������������$O����� ����������*���������� ������������O�$���������������- ���������������������+� ����������������������������1*��������������������������� ����������E����E����������� �����������������������'�) ������!�� ��C�����������������������/����������������-��������C������������(('�����1���������������������������������/���������������'�����+�������������������!�����V!�� �WV897H'QW0���������������!�����V!�� �WV8�"9H'QW0�!�����V!�� �WV2;��?&9'H'QW����������E��������������67"#������������������C������������ ����67"#�������������������E�������������"#����������C�������������- ����������������$O����� ���������������������O�$������������������������1*��������������E�����������������������E����������� ��������!� ����67"#����������67"#����������C����������- ����������������$O������67"#�����������������������O�$��������������!�C�����������������- ����������������$ ��������!����3�����$�P����������������������+� ������������������������- ����������������$Q&2"�� �������!��3��$�P������������������������67��������

Page 138: Java in Datenbanksystemen

�*� ������������� ��

�����������������- ����������������$:�� ���������!��3���$�P����������������������"������!����P�$O�$��������������E������������/��������#�"#�����������K/�����������E����������� ��������!� ���?����� ��67?�������������� ��67"#�����������C������������//����������������������- ����������������$O�����?�������3����O�$����������������/�F���������!�C�������������- ����������������$?������R$�P���PP��P�$3$���������������- ����������������$Q&2"�� �������!�3�$�P�������67���������������������- ����������������$ ��������!���3����$�P������+� �������������������- ����������������$:�� ���������!�3��$�P������"������!�������������E������������/��������#�?���������K/�����������E����������� ���������������897�����!�� ��C���������������!�����V!�� �WV897H'QW�����E����������� ������������ ��������������0���������C��������������������/�$$������������������/M���4������PP������������������P/���������������������������EE

Die Konfigurationsvariable dbconf in Beispiel 4.12 ist als zweidimensionale Matrixdefiniert, welche die Namen verschiedener Zieldatenbanksysteme als Elemente derersten Dimension enthält. (Das erste Element der ersten Dimension spezifiziert denJDBC-ODBC-Treiber, das zweite Oracle, das dritte DB2 und so weiter.) Die zweiteDimension enthält ebenso vier Elemente, die den spezifischen Treibernamen, die spezi-fische URL-Adresse sowie Kennwort und Kennung des jeweiligen Datenbanksystemsenthalten.

Die Java Klassse DBUtils enthält auch fünf Methoden:

� ����'�� �'�������

� ������'�) ���

� ����67"#���������

� ���?����� ��

� �������0

�������

Die entsprechenden Angaben bezüglich der Kennung und des Kennwortes fürjedes Datenbanksystem müssen durch spezifische Angaben Ihres Systems ersetztwerden. Genauso muss die URL-Information für die Datenbanksysteme Oracleund Informix angepasst werden.

Page 139: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �*!

die als allgemeine Methoden implementiert und verwendet werden können. DieMethode initDatabaseDriver() ermöglicht die Registrierung des Treibers des jeweili-gen Datenbanksystems. Der einzige Parameter dieser Methode (database) wird in derzweidimensionalen Matrix dbconf als Parameter für die Festlegung des Zieldaten-banksystems verwendet.

Die zweite Methode connectDataBase() erstellt die Verbindung zum Datenbanksys-tem, wobei sie denselben Parameter wie die Methode initDatabaseDriver() verwen-det.

Die Methode showSQLException() wird aufgerufen (siehe Beispiel 4.11), falls eineAusnahme in Bezug auf eine SQL-Anweisung auftritt. Sie ruft die Klasse SQLExcep-tion auf und gibt die Fehlermeldung und die Fehler-Codes für eine fehlerhafte SQL-Anweisung aus. Die Methode showWarnings() wird in Verbindung mit der CREATEPROCEDURE-Anweisung verwendet, um eventuell aufgetretene Übersetzungsfehlerim Server zu erkennen. Diese Methode dient im Allgemeinen dazu, alle aufgetretenenWarnungen auszugeben.

Die Methode strStr() wiederholt die Zeichenkette, die im ersten Parameter steht, so oft,wie der Wert des zweiten Parameters beträgt (siehe auch Beispiel 4.18).

Alle nachfolgenden Beispiele in diesem Buch verwenden die oben beschriebene Java-Klasse namens DBUtils.

Nachdem wir in Beispiel 4.11 die Verwendung der execute()-Methode für die Ausfüh-rung einer DDL-Anweisung gezeigt haben, werden wir im folgenden Beispiel die Aus-führung einer UPDATE-Anweisung durchführen.

�������

Die Fehlerbehandlung bei der Treiberinitialisierung muss generell von der Fehler-behandlung anderer Schritte getrennt werden. Der Grund dafür ist, dass alle ande-ren Schritte bei einem Fehler eine Instanz der Klasse SQLException liefern,während die Methode Class.forName() eine Instanz der Klasse ClassNotFoundEx-ception erzeugt. (Die Klasse ClassNotFoundException ist eine Unterklasse derException-Klasse.)

�������

Um das JDBC-Programm in Beispiel 4.11 zum Ablauf zu bringen, muss zuerst dieDBUtils.java-Datei übersetzt werden. (Die beiden Dateien müssen sich in demsel-ben Dateiverzeichnis befinden.) Danach wird das JDBC-Programm in Beispiel 4.11übersetzt und zum Ablauf gebracht werden. (Dieselbe Vorgehensweise gilt für allenachfolgenden Beispiele in diesem Kapitel.)

Page 140: Java in Datenbanksystemen

��� ������������� ��

Beispiel 4.13

��������� ������������8��� ����� �'+7C���� ��������������')+��/�')8��� �&9;�7"�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�8�!���� �U����$��������������((��������������������3������������ ����/���������������������������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���:"+;�!�,!���$��������������(( ��� �����67�'+7�;���� ����� �U�����������������- ���������������� �����#�����8�!���$82';*"�������������"*���������������<��/@G@�?:"9"��<��/NMGF$��P�$�9����������X�!���$��������������((;� ���� ����������������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3����������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe ist:

T�����!����>��')�&I8�!���� �U����F�9����������X�!���

ORACLE, INFORMIX, DB2, MySQL

Page 141: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� ���

Beispiel 4.13 zeigt ein weiteres JDBC-Programm, das mit Hilfe einer UPDATE-Anwei-sung eine Reihe der Tabelle mitarbeiter ändert. Das Programm verwendet die execute-Update()-Methode, die ausschließlich für die Änderung von Reihen verwendet wird.Wie aus dem Ergebnis des Beispiels 4.13 ersichtlich, liefert die Methode execute-Update() als Rückgabewert eine Ganzzahl (in diesem Fall 1).

��E�� ���?��G�����������*��)!��������=�����-���-()����������

Mit Beispiel 4.13 haben wir gezeigt, wie man SQL-Anweisungen ausführen kann, fallsdie Anweisung keine Ergebnismenge liefert. Alle SQL-Anweisungen, die eine Ergeb-nismenge liefern, brauchen einen Pufferbereich, wo die Reihen gespeichert undanschließend reihenweise abgearbeitet werden können. Der Grund daür liegt in denUnterschieden zwischen den Sprachen SQL und Java.

SQL ist eine mengenorientierte Sprache. Das heißt, dass einige SQL-Anweisungen wiez.B. SELECT mehrere Reihen (möglicherweise auch keine) als Ergebnismenge liefern.Die Java-Sprache, genauso wie alle anderen prozeduralen Sprachen (C, C++, Cobol),kann nicht gleichzeitig mehrere Datensätze bearbeiten, sondern holt sich einen Daten-satz nach dem anderen.

Damit dieser Unterschied zwischen Java und SQL überbrückt werden kann, wird einDatenpuffer verwendet, in welchen dann alle Reihen, die als Ergebnis eine Reihen-menge liefern, gespeichert werden. Dieser Datenpuffer wird mit einer Art Zeiger bear-beitet, der bei SQL Cursor heißt.

Wie wir schon erläutert haben, wird der Cursor in JDBC mit Hilfe der ResultSet-Schnittstelle und ihrer Methoden implementiert. Die wichtigste Methode dieser Klasseist next(), die die Abarbeitung einzelner Reihen der Ergebnismenge ermöglicht.

Beispiel 4.14 zeigt die Erstellung einer Ergebnismenge mit Hilfe der ResultSet-Schnitt-stelle und ihre Verarbeitung mit der Methode next().

Beispiel 4.14

��������� ������������8��� ����� �������C���� ��������������')+��/�')8��� �H� &9+HQ�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�

ORACLE, INFORMIX, DB2, MySQL

Page 142: Java in Datenbanksystemen

��" ������������� ��

����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//����������������������((;�����S�������� �������������������-�����3����������-��������C�������������- ����������������$T�����!����>��')�&IO�'����� �!���������������'�����1���������$��������������((��������������������3������������ ����/���������������������������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���:"+;�!�,!���$��������������((9� �������!�1�������3������������� �/� �����#�����6���-�$�"7"�*�������������������?:"9"��������������<���)"*?""��FMMM�;�'�NNNN$���������������- ����������������$a��� ����"������ �3$��������������((;� ����!� �9� ������� 3������������((�� ���#�������������� �0������1�����9���������������U���� ��!�������������������� ���#�����C������������������������������/�� �����������F���((�������/�������F���������������������������/�� �����������,��������������������������������/�� �����������G�������������������- ��������������$��<��/�$�P��������������������������- ��������������$��<���/�$�P�����������������������- ���������������$�<������/�$�P��������P$O�$��������������E������������((;� ���� ��������������������������������������������� ���� ���������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3��������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe ist:

T�����!����>��')�&I'����� �!���'�����1���������a��� ����"������ �3��<��/�NMGF��<���/�+��������������������<������/�9������<��/�,ZbF��<���/�I������������������<������/�)�������

Page 143: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� ��*

Im Unterschied zu den Beispielen 4.11 und 4.13 verwendet Beispiel 4.14 die KlasseResultSet, weil die im Beispiel benutzte SQL-Anweisung eine Abfrage ist. Zuerst wirdeine Variable (rs) definiert, die eine Instanz der Schnittstelle ResultSet ist. Mit Hilfe derexecuteQuery()-Methode wird der Variablen rs die Ergebnismenge der Abfrage zuge-wiesen. Die Methode next() ist in einer while-Schleife definiert, damit alle Reihen derErgebnismenge abgearbeitet werden können. Diese Methode liefert den Wert falsezurück, falls keine Reihen zur Abarbeitung anstehen. Die Methode next() kann nur dieReihen einer Ergebnismenge sequenziell abarbeiten. Das heißt, dass der Zeiger aus-schließlich auf die nächste Reihe der Ergebnismenge positioniert werden kann.

Mit Hilfe der getString()-Methode werden alle Werte der aktuellen Reihe geholt. Dabeiwerden die Spaltenwerte mit Hilfe der Indexnummer ermittelt. (Für die Beschreibungder getXXX()-Methoden und des Verfahrens für die Ermittlung von Spaltenwertensiehe den Abschnitt »Ausgabe der Ergebnisse« in diesem Kapitel.)

Bevor wir die erweiterten Möglichkeiten in Bezug auf die Verarbeitung einer Ergebnis-menge zeigen, werden wir die Verwendung von Metadaten mit JDBC erläutern. Diesist notwendig, weil Beispiele mit Scroll-Cursor und der positionierten Änderung denZugriff auf Metadaten verwenden.

��E�� �������*��������

Der Systemkatalog beinhaltet interne Informationen, die jedes Datenbanksystem füreinen reibungslosen Ablauf benötigt. Im Systemkatalog befinden sich Metadaten(Daten über Daten), d.h. Informationen über Datenbankobjekte (Tabellen, Indizes,Sichten usw.).

JDBC unterstützt zwei Schnittstellen für die Darstellung von Metadaten:

� DatabaseMetaData

� ResultSetMetaData.

Die beiden Schnittstellen werden in den nachfolgenden Unterabschnitten erläutert.

����������*�������-()����������

Mit der Schnittstelle DatabaseMetaData können umfassende Informationen u.a. über:

� das Datenbanksystem

� den JDBC-Treiber

� die aktuelle Datenbank

� die in der aktuellen Datenbank existierenden Objekte

abgefragt werden.

Page 144: Java in Datenbanksystemen

��� ������������� ��

Eine Instanz der Schnittstelle DatabaseMetaData kann (über eine aktive Verbindung)durch den Aufruf der Methode getMetaData() der aktuellen ResultSet-Instanzerzeugt werden. Viele Methoden der DatabaseMetaData-Schnittstelle geben die Infor-mation in der Form von ResultSet-Instanzen zurück. Dementsprechend können dieMethoden der ResultSet-Schnittstelle wie getString�� und getInt�� verwendet wer-den, um die Daten aus der Ergebnismenge abzufragen.

Folgende Methoden der DatabaseMetaData-Schnittstelle liefern u.a. als Ergebnis eineInstanz der Klasse ResultSet:

� g�������� ��������������0�������� ����2�����0���������������2�����0������������� ���2������

� ���*��� � �������� �����0� ������� �������2�����0� ������� �������2�����0������VW��-�� �

� ���*���*-�� ��

Die Namen der oben aufgelisteten Methoden sind aussagekräftig, so dass wir auf ihreBeschreibung verzichten werden.

Beispiel 4.15 zeigt die Verwendung der Schnittstelle DatabaseMetaData um dieInformationen über den verwendeten Treiber auszugeben.

Beispiel 4.15

��������� ������������8��� ����� �'�����H���C����(()������3�'����- ��������������������:�� �����������������!����((!���%')�<&')��)��!���1S���������� ����!����� ���K���� ��������������')+��/�')8��� �%')�&')������ ��������������������/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C������������'�� �+��'��!��!�/��������+��'�����������������- ����������������$*����������3�$P!��!����'����������P$O��������������*�������T�� ���3�$P!��!����'�����T�� ��������������������- ����������������$2��!�1�����3�$P!��!����'�� �2��!��������P$O��������������2��!�1��T�� ���3�$P!��!����'�� �2��!���T�� �����P$O�$���������������- ����������������$�- ���� ��1������3$P!��!�����- ��� ������� �����������������- ����������������$������� ��1������3$P!��!���������� ������� ����

ORACLE, INFORMIX, DB2, MySQL

Page 145: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� ��.

�������������- ����������������$�67�I�-���! 3$P!��!�����67I�-���! �����������������- ����������������$������������3$P!��!���������*��������������������- ����������������$�������������� ������ �U�>�3$P!��!� ������ ������������������!2����!��� �����������������- ����������������$&�����%��� ������ �U�>�3�������0����0�������!�$P������������!��!� ������ &����%��� ��P$�$P!��!� ������ ���&����%��� ��P$�$P!��!�������������� ������ 7�����!&����%��� �������������������������((�;����')+'�'�����>��������������������������')8��� ����')+''���� �!��!��������������((;� ���� ������������������������������������������� ������������E��������((;� �U��������%')�� ���������!����3�����������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

� Der Teil der Ausgabe des Beispiels 4.15 sieht folgendermaßen aus:

*����������3�%')��&')��)��!����'),�7H�'77�*�������T�� ���3�,�MMMF��M^�MF�MMMM�2��!�1�����3�'),(�*2��!�1��T�� ���3�M^�MF�MMMM�- ���� ��1������3�')�;+"0H �87708�"9�;+"������� ��1������3�;��HH0�:;90�&��;*0'H "9"��"0H��"9*07�;�"07" *07"�a*:07&�;*"07&�;*"<,07*9H+09"2";*09"27;�"09Ha:*09*9H+0�&8�'"Q0�2;�"0�8)�*9H�a08�;�"�67�I�-���! 3��;770�&++"�*0�&��;*0';[�0 9""0:&89�07&�I0+;Q H7"�0+;Q H7"�HD"0+H�9&�"�&�'0+H�9&�"�&�'�0+H�8*"�0+&�*:�0&7'0&2*H+HD"0�"�&�'�0[";9�������������3� ����!������!����������������� ������ �U�>�3�����&�����%��� ������ �U�>�3�������0�����0�������!�������� ���� �

In Beispiel 4.15 wird eine Instanz (dbmd) der Schnittstelle DatabaseMetaData defi-niert, und dieser wird mit Hilfe der getMetaData()-Methode der Klasse Connectiondie Systeminformation zugewiesen. Die ermittelte Information wird anschließend mitHilfe unterschiedlicher Methoden der Schnittstelle DatabaseMetaData ausgegeben.Zu den verwendeten Methoden gehören u.a. getDriverName(), getDriverVersion(),getSystemFunctions(), getSQLKeywords() usw. (Die Namen aller dieser Methodensind selbsterklärend.)

Page 146: Java in Datenbanksystemen

��/ ������������� ��

Am Ende des Programms wird noch die Funktionalität des Treibers getestet: Mit derFunktion supportsStoredProcedures() wird überprüft, ob der Treiber die gespeicher-ten Prozeduren unterstützt, während die Methode supportsOuterJoins() die Unter-stützung des Outer Joins überprüft. (Die beiden oben erwähnten Methoden sind nurzwei Beispiele aus der zahlreichen Gruppe von Methoden, deren Namen mit »sup-ports« anfangen und die Funktionalität des JDBC-Treibers in Bezug auf verschiedeneSQL-Sprachelemente überprüfen.)

���;����0�5�����#0�2������

Die ResultSetMetaData-Schnittstelle beschreibt die Struktur einer spezifischen Instanzder Klasse ResultSet. Diese Schnittstelle wird bei den vorbereiteten SQL-Anweisungenverwendet, um Information über Datenbankobjekte zu erfragen. Generell wird eineInstanz der ResultSetMetaData-Schnittstelle durch den Aufruf der Methode getMeta-Data�� erzeugt.

Folgende Methoden der ResultSetMetaData-Schnittstelle liefern z.B. die Informationin Bezug auf Spalten einer Tabelle:

� getColumnCount()

� getColumnTypeName()

� getColumnLabel()

� getColumnDisplaySize().

Die Methode getColumnCount() ermittelt, wie viele Spalten eine Ergebnismenge hat.Diese Information ist wichtig, um zu wissen, wie oft eine Schleife, die Tabellenspaltenverarbeitet, wiederholt werden muss (siehe Beispiel 4.16).

Die Methode getColumnType() gibt den Datentyp jeder Spalte zurück (siehe auch Bei-spiel 4.16). Mit Hilfe der Methode getColumnLabel() kann der Name der Spalte geholtwerden, damit diese als Spaltenüberschrift benutzt wird. Die Methode getColumnDis-playSize() gibt vor, wie lang die Ausgabe eines Spaltenwertes sein soll.

Beispiel 4.16 zeigt die Verwendung der ResultSetMetaData-Schnittstelle.

�������

Die Hilfsklasse DBUtils stellt weiterhin eine Methode zur Abfrage aller vom Trei-ber unterstützten Funktionen zur Verfügung.

Page 147: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� ��4

Beispiel 4.16

��������� ��������������������������8��� ����� �9�+'C���� ��������������')+��/�')8��� �'),�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�$��������������((��������������������3������������ ����/���������������������������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���������������:"+;�!�,!���$���������������- ����������������$)���������������������*��������������3$��������������(("�������� ��3�����������������������������/������)������!9�!������H���������9�!��������������������- ������������!7������������������� �/� �����#�����6���-�$�"7"�*��� 9&+�$�P��������������������9� ������+��'��� �!�/�� ����+��'��������������������������/�� �!�������������������������������- ����������������$*������$�P�������P�$����������!���������������"���� ������3$���������������- ����������������$����������*-��)� ����������877$������������������������/F���4/��������PP�C�����������������- ����������������� �!����������������P$�$P� �!��������������������������*-��������P$�$P� �!�� ?���������P$�$P� �!�� ������������������������E������������((;� ���� �������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3���������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�����������

ORACLE, INFORMIX, DB2, MySQL

Page 148: Java in Datenbanksystemen

��� ������������� ��

��������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe des Beispiels 4.16 sieht folgendermaßen aus:

T�����!����>��')�&I)���������������������*��������������3�������*�����������������������!��"���� ������3����������*-��)� ����������877+<�9�H�*����������M29<�9��:;9����������M;8 a;)"��:;9����������F"H��*<';*�';*"������F

In Beispiel 4.16 wird zuerst als Bildschirmeingabe der Name einer Tabelle erwartet.Dieser Name wird anschließend der String-Instanz tabelle zugewiesen und im weite-ren Verlauf des Programms für die Ermittlung der Tabelleneigenschaften benutzt. MitHilfe der Methoden getColumnName(), getColumnTypeName(), isWritable() undisNullable() werden folgende Spalteneigenschaften: Namen, Datentypen, ob Spalten-werte überschreibbar sind und ob Spalten NULL-Werte enthalten können (in dieserReihenfolge) geholt und ausgegeben.

Nachdem wir die beiden wichtigen Klassen in Bezug auf Metadaten durch Beispieleerläutert haben, werden wir Beispiele für einen Scroll-Cursor und das positionierteÄndern zeigen. Die beiden Beispiele verwenden die Information bezüglich der Meta-daten.

��E�D -(�!�������!�

JDBC 2.0 unterstützt den Scroll-Cursor, mit dem die Positionierung innerhalb einerErgebnismenge wesentlich flexibler als mit einem Non-Scroll-Cursor gestaltet werdenkann. Beispiel 4.17 zeigt die Verwendung eines solchen Cursors.

Beispiel 4.17

��������� ������������8��� ����� �9���� �������C���� ��������������')+��/�')8��� �'),�����((���S������T��������U��')�D���������

ORACLE, INFORMIX, DB2, MySQL

Page 149: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� ��!

���� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�;������� �U�������$��������������((��������������������3������������ ����/�������������������9� �������*[2"<��9&77<H��"��H*HT"0�������������9� ��������&��89<9";'<&�7[��������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���:"+;�!�,!���$��������������(( ��� �����67�'+7�;���� ����� �U����������������� �/� �����#�����6���-�$�"7"�*��� 9&+�����������$��������������9� ������+��'��� �!�/�� ����+��'�������������������������� 0�������������������� �/�� �!�������������������������������������/F���4/���� ���PP�������������((�������U��� ���������� �����0��� ������������������������((�����7���>��������U���������������������- ��������������� �!�����������������P�')8��� � �����������������������$�$0� �!����������'� ��-��>����������������������� �!��������������������������������������������- ����������������$$��������������� �� ����������������!�������������C���������������������/F���4/���� ���PP����������������������- ��������������� ����&��������P���������������������')8��� � ������$�$0� �!����������'� ��-��>��������������������������� ����&�������������������������������������������������- ����������������$$��������������E������� �������� ����������������((;� ���� ���������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3�����������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Page 150: Java in Datenbanksystemen

�.� ������������� ��

Die Ausgabe des Beispiel 4.17 ist:

T�����!����>��')�&I;������� �U�������+<�9�������+<�;+"��������������+<T&9�;+"�����������;)*<�9,bZZN������+�>�������������������������������������F,ZbF�������I�����������������)�������������������,NMGF�������+�������������������9������������������,,NG.\������2��� ���������������;�!�� �������������,FbGF\������+U������������������a������������������FFMFM,������:�������������������2������������������G,ZG.b������I�������������������:� ����������������G

In Beispiel 4.17 werden die Reihen der Tabelle mitarbeiter rückwärts gelesen. Damitein Scroll-Cursor verwendet werden kann, wird die Konstante TYPE_SCROLL_INSENSITIVE für den Parameter resultSetType verwendet. Mit Hilfe der MethodegetColumnCount() der Schnittstelle ResultSetMetaData wird die Anzahl der Spaltender Tabelle mitarbeiter ermittelt. Dieser Wert wird in der for-Schleife verwendet, umSpaltenüberschriften (siehe die Ausgabe des Beispiels) auszugeben.

Die Methode last() wird verwendet, um den Cursor auf die letzte Reihe der Ergebnis-menge zu setzen. Anschließend wird innerhalb einer do/while-Schleife die previous()-Methode aufgerufen und jede gelesene Reihe ausgegeben.

��E�� �!����!�������V��������N'(�(�����&���O

Wie wir schon erläutert haben, ist ein Cursor im Allgemeinen nicht notwendig, fallsman Änderungen an einer Tabelle durchführen will. Im speziellen Fall aber kann dieVerwendung eines Cursors zwingend sein, falls der Benutzer innerhalb einer Reihen-menge gezielt Änderungen durchführen will.

Die SELECT-Anweisung ist die einzige SQL-Anweisung, die eine Ergebnismengeerstellt, und deswegen die Verwendung des Cursors voraussetzt. Die anderen DML-Anweisungen, wie UPDATE und DELETE verwenden in der Regel keinen Cursor, weildas System nach der Änderung generell nur die Anzahl der modifizierten Reihenzurückliefert. Trotzdem kann die Verwendung des Cursors bei solchen Anweisungenwie DELETE und UPDATE manchmal zwingend notwendig sein, falls nur einzelneReihen gezielt modifiziert bzw. gelöscht werden sollen. (Mit anderen Worten will derBenutzer eine Reihenmenge zur Verfügung haben und danach entscheiden, welcheReihen geändert werden sollen und welche nicht.) Dieser Vorgang kann mit Hilfe dersogenannten positionierten Änderung (positioned update) durchgeführt werden.

�������

Die Änderungsoperationen, die mit einem solchen Cursor ausgeführt werden kön-nen, sind Modifikation von Spaltenwerten (UPDATE) und Löschen von Reihen(DELETE).

Page 151: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �.�

Im Unterschied zum Cursor, der ausschließlich für die Abfrage definiert ist, muss einÄnderungs-Cursor zusätzliche Syntaxangaben enthalten, damit er als solcher vomSystem erkannt wird. Der wichtigste Punkt ist, dass der Wert des Parameters result-SetConcurrency auf CONCUR_UPDATABLE gesetzt wird. (Alle anderen Besonder-heiten der positionierten Änderung werden im Anschluss an das folgende Beispielerläutert.)

Beispiel 4.18 zeigt, wie man mit JDBC positionierte Änderungen einer Ergebnismengedurchführen kann. Dieses Programm kann nicht mit MySQL verwendet werden, weilder entsprechende Treiber dieses Datenbanksystems positioniertes Ändern nichtunterstützt.)

Beispiel 4.18

��������� ��������������������������8��� ����� �2� 8�!��C���� ��������������')+��/�')8��� �&9;�7"�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�$��������������((��������������������3������������ ����/�������������������� �*[2"<��9&77<H��"��H*HT"�0�������������� ��&��89<82';*;)7"��������������'�� �+��'��!��!�/��������+��'�����������������- ����������������$��� �����0���!�������� �������������������� �U�>�3�$P!��!� ������ 9� ����������������-��������������� �*[2"<��9&77<�"��H*HT"0�� ��&��89<82';*;)7"����������������- ����������������$��� �����0�������!�������� �������������������� �U�>�3�$P!��!� ������ 9� ����������������-��������������� �*[2"<��9&77<�"��H*HT"0�� ��&��89<9";'<&�7[����������������- ����������������$H���� �����0���!�������� �������������������� �U�>�3�$P!��!� ������ 9� ����������������-��������������� �*[2"<��9&77<H��"��H*HT"0�� ��&��89<82';*;)7"����������������- ����������������$H���� �����0�������!�������� �������������������� �U�>�3�$P!��!� ������ 9� ����������������-�

ORACLE, INFORMIX

Page 152: Java in Datenbanksystemen

�." ������������� ��

��������������� �*[2"<��9&77<H��"��H*HT"0�� ��&��89<9";'<&�7[������������������������������������- ����������������$2� ���������� �82';*"������ �U�>�3$P�������������!��!� ������ 2� ������!8�!��������������������- ����������������$2� ���������� �'"7"*"������ �U�>�3$P��������������������!��!� ������ 2� ������!'����������������������(( �����!�������� ������� � ��!������ ����!������U��!��������������((���������'�����10���������c�!�����������������((���!���"������ ������>�����S�����������������������')+��//�')8��� �H� &9+HQ�����������������((0����!�+8���������������!������������������� �/� �����#�����6���-�$�"7"�*��0����!� 9&+�����������������������������������<�����������FMMMM��!�FMMMMM$���������������� ��((�����������+d��"������&9;�7"�������������!������������������� �/� �����#�����6���-�$�"7"�*��<��0�<���0������������������<������0��<��� 9&+�����������������������������������<�����������FMMMM��!�FMMMMM$��������������������������������9� ������+��'��� �!�/�� ����+��'������������������������ �/�� �!�������������������������������������� ���#�����������������C���������������������/F���4/���� ���PP����������������������- ��������������� ����&��������P���������������������')8��� � ������$�$0� �!����������'� ��-��>��������������������������� ����&�������������������������������������������������- ����������������$$�������������������- ���������������$O�+������������!�� ��9����������������������S ������(��_O�$�����������������������/�����)������!9�!�����������������������H���������9�!����- �����������!�����������������������//@%@�ee�//@@��� �!�����9�����������������E������������((;� ���� ������������������������������������ ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3����������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Page 153: Java in Datenbanksystemen

8���9�����1����1���(�)������0:�#��,������� �.*

Die Ausgabe ist:

T�����!����>��')�&I��� �����0���!�������� �������� �U�>�3�������� �����0�������!�������� �������� �U�>�3�����H���� �����0���!�������� �������� �U�>�3�����H���� �����0�������!�������� �������� �U�>�3�����2� ���������� �82';*"������ �U�>�3�����2� ���������� �'"7"*"������ �U�>�3�����F,^.Z�����������������+�1� ���������������������������������G+������������!�� ��9������S ������(��_

Im ersten Teil des Beispiels 4.18 wird mit Hilfe der Methoden der Klasse DatabaseMe-taData untersucht, ob der verwendete Treiber verschiedene Cursor-Arten sowie posi-tioniertes Löschen und Ändern unterstützt. Dies ist auch unbedingt notwendig, weileinige Treiber nicht alle im Beispiel getesteten Erweiterungen des JDBC 2.0 unterstüt-zen. (Die erste Zeile des Beispiels 4.18 zeigt auch, dass das positionierte Ändern vomIBM DB2 z. Zt. nicht unterstützt wird.)

Ein weiteres Merkmal der positionierten Änderung ist, dass Oracle und Informix spe-zifische Angaben in der SELECT-Anweisung, die die Änderungsmenge festlegt, ver-langen. Während Oracle die Verwendung von »*« in der SELECT-Liste nicht erlaubt(d.h. die Spaltennamen müssen explizit angegeben werden), muss bei Informix dieSELECT-Liste unbedingt die Spalte ROWID enthalten. (ROWID ist ein interner Daten-typ des Informix-Systems, der vom Benutzer für die Definition einer Spalte nichtbenutzt werden kann. Jeder Reihe einer Tabelle wird ein ROWID-Wert zugewiesen, derdie Reihe dann intern eindeutig kennzeichnet.)

Im mittleren Teil des Beispiels wird die Methode getColumnCount() der KlasseResultSetMetaData verwendet, um die Anzahl der Spalten der Tabelle zu ermitteln.Dies ist notwendig, weil anschließend dieser Wert für die formatierte Ausgabe derSpaltenwerte verwendet wird (siehe die Ausgabe des Beispiels 4.18.)

In folgender Schleife:

�����/F���4/���� ���PP��- ��������������� ����&��������P')8��� � ������$�$0� �!����������'� ��-��>������ ����&��������������������������������

werden die einzelnen Spalteninhalte mit korrekter Breite ausgegeben. Dazu wirdzuerst das Objekt selbst über rs.getObject(i) ausgegeben, gefolgt von einer leeren Zei-chenkette, die die restliche Spaltenbreite ausfüllt. Die Methode strStr() der KlasseDBUtils wiederholt die Zeichenkette, die im ersten Parameter steht, so oft, wie derWert des zweiten Parameter beträgt. In diesem Fall ist die Breite der leeren Zeichen-kette die Gesamtbreite der Spalte (rsmd.getColumnDisplaySize(i)) minus der Längedes dargestellten Spalteninhalts. Über die Methode toString() des gelesenen Objektes

Page 154: Java in Datenbanksystemen

�.� ������������� ��

rs.getObject(i) wird das Objekt in ein String-Objekt überführt, von dem mit derMethode length() die Länge ermittelt wird.

Anschließend wird für die ausgegebene Reihe eine Antwort des Benutzers erwartet, obdiese gelöscht werden soll oder nicht. Bei der Antwort »J(a)« (oder »j(a)«) wird dieReihe, auf die der Cursor positioniert ist, mit Hilfe der deleteRow()-Methode derResultSet-Schnittstelle entfernt.

��0 �������3!�����������-H'���G��������

Im vorherigen Abschnitt haben wir gezeigt, wie die unterschiedlichen SQL-Anweisun-gen mit Hilfe der Methoden execute(), executeQuery() und executeUpdate() derKlasse Statement übersetzt und ausgeführt werden können. Für alle in den Beispielen4.11-4.14 verwendeten SQL-Anweisungen gilt gemeinsam, dass sie zur Übersetzungs-zeit bekannt sind.

Im Unterschied dazu ist es oft notwendig, eine ganze SQL-Anweisung am Bildschirmeinzugeben, die dann vom System analysiert und ausgeführt wird. Anwendungen, diesolche Anweisungen beinhalten, erfordern die Vorbereitung der Anweisung zur Lauf-zeit des Programms. Deswegen werden sie vorbereitete Anweisungen genannt.

Um die Formulierung der SQL-Anweisungen zur Laufzeit zu ermöglichen, ist es emp-fehlenswert, die Klasse PreparedStatement zu verwenden. Diese Klasse ist eine abge-leitete Klasse der Klasse Statement und bereitet die Ausführung einer SQL-Anweisungvor. Eine Instanz der Klasse PreparedStatement nimmt eine SQL-Anweisung auf undführt eine Vorübersetzung durch. In dieser Instanz ist dann die Anweisung in der vor-übersetzten Form gespeichert.

Diese Vorgehensweise bringt signifikante Vorteile im Vergleich zu der Verwendung derSQL-Anweisungen, die zur Übersetzungszeit bekannt sind:

� die wiederholte Vorübersetzung einer SQL-Anweisung entfällt.

� die notwendigen Parameter können zur Ablaufzeit und nach der Festlegung derAnweisung angegeben werden.

� Falls eine SQL-Anweisung mehrmals in einem JDBC-Programm ausgeführt wer-den muss, bringt ihre Vorbereitung einen signifikanten Performance-Gewinn, weilbei jeder wiederholten Ausführung die Übersetzung der Anweisung nicht gemachtwerden muss. Genauso können Parameter in einer vorbereiteten SQL-Anweisungerst in einem zweiten Schritt zugewiesen werden, was eine weitere Flexibilität mitsich bringt (siehe Beispiel 4.19).

Page 155: Java in Datenbanksystemen

�� �������(��������0:�#��,������� �..

Eine Instanz der Klasse PreparedStatement wird durch den Aufruf der Methode pre-pareStatement() der Connection-Klasse erzeugt. Die Syntax dieser Methode sieht fol-gendermaßen aus:

2�����!������������������������������� ���

wo der Parameter sql zur Ablaufzeit durch eine SQL-Anweisung ersetzt wird.

Beispiel 4.19 zeigt ein JDBC-Programm, das eine beliebige SQL-Anweisung (ohneParameter) zur Laufzeit als Eingabe akzeptiert, sie vorbereitet und anschließend aus-führt.

Beispiel 4.19

��������� ��������������������������8��� ������������ �2�*+*C���� ��������������')+��/�')8��� �H� &9+HQ�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�$�������������� ����/�������������������������������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���������������:"+;�!�,!���$��������������(()����>��������3�������������- ����������������$)��������������������'+7�;���� �������3$��������������������� ��F�/������)������!9�!��������������������H���������9�!����- ������������!7������������������((!-��� �����67�;���� ���������������������������2�����!���������� ����/��������������������� ��F���������������� �����#��������

�������

Die Ausführung einer vorbereiteten SQL-Anweisung erfolgt (genauso wie bei denAnweisungen, die zur Übersetzungszeit bekannt sind) durch den expliziten Aufrufder Methoden execute(), executeQuery() oder executeUpdate(), die die Klasse Pre-paredStatement von der Klasse Statement erbt.

ORACLE, INFORMIX, DB2, MySQL

Page 156: Java in Datenbanksystemen

�./ ������������� ��

�������������- ����������������$;���� ����� ���U���$��������������((;� ���� ����������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3���������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe des Beispiels 4.19 ist:

T�����!����>��')�&I)��������������������'+7�;���� �������3;���� ����� ���U���

Beispiel 4.19 enthält je eine Instanz der Klassen Statement und PreparedStatement.Mit der Instanz der Klasse Statement wird die zur Übersetzungszeit bekannte SQL-Anweisung SET CURRENT SCHEMA übersetzt und ausgeführt, während die Instanzder Klasse PreparedStatement für eine vorbereitete SQL-Anweisung verwendet wird.Mit Hilfe der Ein/Ausgabeklasse BufferedReader und der Methode readLine() wirddie Zeichenkette, die die vorbereitete SQL-Anweisung darstellt, am Bildschirm zuersteingelesen und der String-Variablen sql1 zugewiesen. Die anschließende prepare-Statement()-Methode erstellt eine Instanz der Klasse PreparedStatement, die dannvon der execute()-Methode ausgeführt wird.

Mit der Klasse PreparedStatement ist es auch möglich Eingabeparameter einer vorbe-reiteten SQL-Anweisung zu spezifizieren. Beispiel 4.20 zeigt dies.

Beispiel 4.20

��������� ��������������������������8��� ������������ �2�*+*<���C���� ��������������')+��/�')8��� �H� &9+HQ�����((���S������T��������U��')�D������������� ��������������������/������

ORACLE, INFORMIX, DB2, MySQL

Page 157: Java in Datenbanksystemen

�� �������(��������0:�#��,������� �.4

���� �������������� ����/���������� �����2�����!���������� ����/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�$��������������((��������������������3������������ ����/���������������������������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���������������:"+;�!�,!���$��������������(("�������� ��3������������������� ��F��������������������������������������!�C�((�?��!��������� �2�����!���������1����1�����������������������/��� ������������������!�C�(("��������� �����!�U�����U������������������������- ����������������$)��������������������'+7����������������������;���� ��������������2����������3$�����������������������- ����������������$)�� ����3�82';*"������������������������������"*���<���/�@�,@�?:"9"��<���/�_$���������������������� ��F�/������)������!9�!���������������������������H���������9�!����- ������������!7����������������������E������� ��F���!�#&��@_@�//�F���������������������-C��((!-��� �����67�;���� ������������������������������������ ����/��������������������� ��F�������������������E�����"#���������#�C���������������������- ����������������$H�1����1���'+7�;���� ���K$����������������������������/����������������������E������������E�������������������������((�2������������� ��3�������������- ����������������$)����������������!���2��������������3$���������������������������/�����)������!9�!�������������������H���������9�!����- �����������!7������������������((�"����+S�����1���0������)����>��������>�� ����������������((�H���������!��������2�������>������� ����!��3��������������-C����������������� ���� ��H���F0�H��������� �H������������������������E�����"#����������C����������������� ���� ���������F0�������������������E���������������� �����#��������C�((�9� �������� �"������ ����������������!��C�������������������������- ����������������$����������9� ������$������������������E����������������������� �������+���9� ��� ���``

Page 158: Java in Datenbanksystemen

�.� ������������� ��

������������������� �������8�!����������//��F���������������E�������������� ��((���� �1�����"������ �������������3�����������������- ����������������� �������8�!���������P$�9����������������������1���� ����$��������������((;� ���� ���������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Ausgabe des Beispiels:

T�����!����>��')�&I)��������������������'+7�;���� ��������������2����������3)�� ����3�82';*"����������"*���<���/�@�,@�?:"9"��<���/�_82';*"����������"*���<���/�@�,@�?:"9"��<���/�_)����������������!���2��������������3FMFM,G�9������1���� ����

Beispiel 4.20 ist bis zum Programmteil, wo der Parameterwert gelesen wird, fast iden-tisch mit dem vorherigen Beispiel. Deswegen werden wir nur das Programm ab demTeil »Parameterwert lesen« beschreiben.

Zuerst wird die Eingabe des vorher im PreparedStatement festgelegten Parameterserwartet. Hierfür wird die readLine()-Methode der Klasse BufferedReader verwendet.Um dem BufferedReader mitzuteilen, dass aus der Standardeingabe, also ausSystem.in gelesen wird, muss dieser Eingabestrom in dessen Konstruktor übergebenwerden. Da die Instanz der BufferedReader-Klasse einen InputReader (anstatt des imSystem vorhandenen InputStreams) verlangt, muss vorher noch aus System.in eineInstanz der Klasse InputStreamReader erzeugt werden. Damit hat der Benutzer dieMöglichkeit sowohl Zahlen als auch Zeichenketten einzugeben.

Um festzustellen, welcher Typ eingelesen wird, versucht die Anweisung: H��������� �H���������

die eingegebene Zeichenkette in eine Zahl zu konvertieren. Falls dies gelingt, wird dergelieferte Zahlenwert der Methode setInt() der PreparedStatement-Klasse übergeben.

Page 159: Java in Datenbanksystemen

���6��������������0��)����������&��2��� '�(1������ �.!

Falls die Eingabe außer Ziffern auch andere Zeichen enthält, wird hier eine Ausnahmeauftreten. In diesem Fall geht das Programm davon aus, dass es sich um eine Zeichen-kette handelt, die im catch-Block mit Hilfe der setString()-Methode zugewiesen wird.

Nach der Ausführung der Instanz der Klasse PreparedStatement mit Hilfe der exe-cute()-Methode kann nun entweder eine Ergebnismenge vorliegen oder ein Zähler mitden geänderten Reihen. Falls die Methode execute() true zurückliefert wissen wir, dasseine Abfrage abgesetzt wurde. Mit Hilfe von pstmt.getMoreResults() können die ein-zelnen Reihen der Ergebnismenge abgefragt und innerhalb der Schleife verarbeitetwerden. (Dieser Vorgang wurde im Beispiel weggelassen.) Falls die Methode execute()false zurückliefert, d.h. keine Abfrage ausgeführt wurde, wird mit Hilfe vonpstmt.getUpdateCount() die Anzahl der von der Anweisung betroffenen Reihen aus-gegeben.

Damit kann der Anwender bei der Ausführung des Beispiels 4.20 z.B. folgende SQL-Anweisungen zur Ablaufzeit spezifizieren:

82';*"����������"*���<��@�,@�?:"9"��<���/�_'"7"*"� 9&+������������?:"9"��<����/�_

und anschließend in einem zweiten, separaten Schritt den fehlenden Parameter amBildschirm angeben.

��A ������������������-����%�����������#��()���� ��!"������

Die SQL-Anweisungen können in Anweisungsgruppen, die bei JDBC batch heißen,zusammengefasst werden. Dementsprechend ist ein batch eine Folge von SQL-Anwei-sungen, die als eine Einheit an das Datenbanksystem zur Ausführung gesendet wer-den. Diese Gruppierung bringt deswegen einen gewissen Performance-Vorteil mitsich, weil nicht jede Anweisung separat übersetzt und ausgeführt werden muss.

Einen wesentlich größeren Performance-Vorteil können die gespeicherten Prozeduren(stored procedures) bringen. Sie werden mit Hilfe der CREATE PROCEDURE-Anwei-sung erstellt und genauso wie Tabellen und Sichten als Objekte der Datenbank gespei-chert. (Eigenschaften der gespeicherten Prozeduren sind in Kapitel 1 ausführlichbeschrieben.)

Für die Abarbeitung der gespeicherten Prozeduren bietet JDBC die Klasse Callable-Statement. Diese Klasse ist der Klasse PreparedStatement sehr ähnlich. Der wichtigsteUnterschied ist, dass die erste die Methode prepareCall() enthält, während die zweitedie (verwandte) Methode prepareStatement() hat. (Die Methode prepareCall() erlaubtdie Angabe des Namens der Prozedur, die aufgerufen werden soll.)

Page 160: Java in Datenbanksystemen

�/� ������������� ��

Beispiel 4.21 zeigt eine Anwendung, die eine Oracle- bzw. Informix-Prozedur mitHilfe der Methode prepareCall() aufruft. (Dieses Beispiel läuft nicht mit MySQL, weildieses Datenbanksystem gespeicherte Prozeduren nicht unterstützt.)

Beispiel 4.21

��������� ��������������������������8��� ����� ���*+*C���� ��������������')+��/�')8��� �&9;�7"�����((����S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C�������������- ����������������$T�����!����>��')�&IO�$��������������((��������������������3������������ ����/���������������������������������((�' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���������������:"+;�!�,!���$��������������'�� �+��'��!��!�/��������+��'�������������������!��!� ������ �����!2����!��� ���C�������������������')+��//�')8��� �&9;�7"��((&9;�7"3�������������������� �����#������$�9";*"�&9�9"27;�"�29&�"'89"����������������������������<����������>��������'" ;87*�M��;��)"aH������������������������!�������1�� ����������/��������P��������������������������������>���(FMM���"�'�$�������������������� �����')+��//�')8��� �H� &9+HQ��((�H� &9+HQ����������������C����������������������-C������������������������ �����#������$'9&2�29&�"'89"��������������������������������<������$����������������������E���������������������������67"#����������C��������������������������������/������"������!�����������������������������������//��\^.������������������������������- ����������������$+����!�����������������������������������������!��$����������������������E�������������������� �����#������$�9";*"�29&�"'89"

ORACLE, INFORMIX

Page 161: Java in Datenbanksystemen

���6��������������0��)����������&��2��� '�(1������ �/�

�������<����������>����H�*�'" ;87*�M����!������1�� ����������/��������P�����������>���(FMM���"�'�29&�"'89"�$������������������E����������������((>���;� �U����������+S�����3����������������(( �����#������$"Q"�8*"�29&�"'89"��������<�������Z������������������((�"����������?����� �� ���������������������')8��� � ���?����� � �������?����� ��������������������((������������������>������������������������������������� ����/���������������$C���������������������������<��������_��E$������������������((������������������� ��������>���������������������')8��� � ���?����� �� �������?����� ��������������������((�2�������F����Z� ��>������������������� ���� ��H���F0�Z������������������((�2��>�!���� �U��������������������� �����#������������������������� ������� ���������������������- ����������������$2��>�!���� ���U���$��������������E�������������� ������������������- ����������������$'�����1������ �U�>��1������������������������������������ $��������������((�;� ���� ��������������������������������������������� ������� ����������������������� ������������E��������((�;� �U��������%')�� ���������!����3���������������������((������67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe des Beispiels 4.21 ist:

T�����!����>��')�&I2��>�!���� ���U���

In Beispiel 4.21 wird zuerst mit dbmd.supportsStoredProcedures() überprüft, ob derTreiber die gespeicherten Prozeduren unterstützt. Falls ja, wird überprüft, ob es sichum Oracle oder Informix handelt.

Falls das Zieldatenbanksystem Oracle ist, wird mit Hilfe der CREATE OR REPLACEPROCEDURE-Anweisung eine Oracle-Prozedur innerhalb des Programms erstellt. (In

Page 162: Java in Datenbanksystemen

�/" ������������� ��

der Praxis wird eine solche Prozedur im voraus vom Datenbankadministrator erstellt.)Falls Informix das ausgewählte System ist, wird mit Hilfe der CREATE PROCEDUREdieselbe Prozedur erstellt.

Die Prozedur erhoehe_mittel, die in beiden Fällen erstellt wird, erhöht Mittel aller Pro-jekte der Beispieldatenbank um einen gewissen Prozentsatz.

Die zwei wichtigsten Anweisungen des Beispiels 4.21 in Bezug auf die Klasse Calla-bleStatement sind:

���������������� ���/��������������$C�����������<�������_�E$�� ���� ��H���F0�Z��

Mit der ersten Anweisung wird die gespeicherte Prozedur ausgeführt. In der CALL-Anweisung muss anstelle jedes Parameters das Zeichen »?« als Platzhalter verwendetwerden. Bei der Ausführung wird jedes dieser Zeichen durch den entsprechendenWert ersetzt. (Die Methode setInt() gibt an, dass der erste Parameter der gespeichertenProzedur durch den Wert 5 ersetzt werden soll.)

��W �##������!���%%������

Ein Applet ist ein Programm, das in der Java-Sprache implementiert und mit Hilfeeines Browsers oder AppletViewer ausgeführt wird. (AppletViewer ist ein Dienstpro-gramm der Firm Sun für die Ausführung von Applets.)

Wie wir schon in Kapitel 3 erörtert haben, wird die main()-Methode eines Java-Pro-gramms von JVM (Java Virtual Machine) verwendet, um dieses auszuführen. Dement-sprechend benutzt der Browser (oder AppletViewer) die start()-Methode des Applets,um die Programmausführung zu starten. Vor Aufruf der start()-Methode wird dieinit()-Methode aufgerufen, um das Applet zu initialisieren.

Das Quellprogramm eines Applets ist in einer .java-Datei gespeichert. Das übersetzteProgramm befindet sich in einer (oder mehreren) .class-Dateien. Falls das übersetzteProgramm von einem Browser ausgeführt werden soll, muss eine HTML-Datei erstelltwerden, die den Pfad zum Applet enthält.

�������

Obwohl es sich bei der Prozedur erhoehe_mittel um eine sehr einfache gespei-cherte Prozedur handelt, können Sie in Beispiel 4.21 sehen, welche signifikantensyntaktischen Unterschiede in ihrer Erstellung bei Oracle und Informix vorliegen.(Wie wir schon in Kapitel 1 erläutert haben, haben alle Hersteller ihre spezifischenErweiterungen in Bezug auf Prozeduren, trotz der erfolgten Standardisierung die-ses Datenbankobjektes.)

Page 163: Java in Datenbanksystemen

�&&��#'�(���))����� �/*

Die allgemeine Vorgehensweise, um ein Applet zu erstellen und auszuführen, kann infünf Schritte unterteilt werden:

1. ein Java-Applet erstellen und dieses in eine Datei mit dem Suffix .java speichern

2. den Quell-Code übersetzen

3. die HTML-Seite, die das übersetzte Applet aufruft, erstellen

4. die HTML-Seite mit dem übersetzten Applet mit Hilfe des Tags namens <APPLET>verbinden

5. das Applet im Browser (oder mit Hilfe des AppletViewers) ausführen.

Beispiel 4.22 zeigt ein Java-Applet.

Beispiel 4.22

((�����!��������������!�� ��;������3((4%')<������5�������%')�O������;��������8��� O')8��� ��� %')�O������;�������� ��������� ������������8��� ��������������������������������a����� �������������*�#�;����� �������;�������#���! �;�����C���� ��������������')+��/�')8��� �'),�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((�"����*�#�;��0�,M�D����������0�\M�D������������������ �����*�#�;�����#��/�����*�#�;���,M0\M������((���������������������������������������������������!� ���������C������((!���;������!���*�#�;������>��U�����������!!���#�����������((!���*�#�;�������������������>��U�������������#������!�$;�������� �����O�$������������ �>��.MM0GMM������������K')8��� �����'�� �'������')+���������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C��������������#������!�$T�����!����>��')�&IO�O�$��������������((��������������������3������������ ����/���������������������

ORACLE, DB2, INFORMIX, MySQL

Page 164: Java in Datenbanksystemen

�/� ������������� ��

������������((' ����!�! ������X�����Y��U��'),������!������KKK�������������')+��//�')8��� �'),������������ �����#������$�"*��899"�*���:"+;�;'+H�H�*9;*&9$�����������(( ��� �����67�'+7�;���� ����� �U���������������#������!�$ U����� 3��"7"�*��� 9&+�����������O�O�$������������ �/� �����#�����6���-�$�"7"�*��� 9&+�����������$�����������9� ������+��'��� �!�/�� ����+��'������������������������ 0������������������ �/�� �!�����������������������������������/F���4/���� ���PP��((�������U��� ���������������������� �����0��� �����������������7���>��������U������������������#������!�� �!�����������������P�')8��� � ������$�$0������������������� �!����������'� ��-��>������������������������� �!�����������������������������������������#������!�$O�$������������������ ���#�������������C�����������������/F���4/���� ���PP����������((�?������ �����0��� �����������������7���>��������U���������������������#������!�� ����&��������P�')8��� � ������$�$0���������������������� �!����������'� ��-��>��������������������������� ����&����������������������������������������������#������!�$O�$�����������E������������((;� ���� ����������������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3�����������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C��������������#������!�$O���8���1������ ���������������������O�$������������������������1*��������������E����E����(("�!������+��E

Die Klasse SelectApplet führt die Abfrage

�"7"�*��� 9&+������������

durch und gibt das Ergebnis am Bildschirm aus. Da das Programm nur unwesentlichvon den vorherigen Beispielen (wie z.B. Select.java) abweicht, wird nur auf die Unter-schiede, die zwischen einem Java-Programm und einem Applet bestehen, eingegan-gen.

Page 165: Java in Datenbanksystemen

�&&��#'�(���))����� �/.

Zu Beginn werden zwei Pakete importiert, welche alle Klassen für die graphische Aus-gabe enthalten:

������������a����� �������������*�#�;���

Die Deklaration des Applets erfolgt direkt in der Klassendefinition durch die Erweite-rung der Klasse Applet (bzw. der Klasse Japplet bei der erweiterten GraphikbibliothekSwing). Durch diese Erweiterung stehen nun spezielle Applet-Methoden zur Abfrageder Parameter des HTML-Applet-Tags bzw. zum Ermitteln des graphischen Kontextesdes Applets zur Verfügung. Da Applets nur in einer graphischen Umgebung Datenausgeben können (und nicht in einer Konsole wie bei einer Java-Anwendung), wird imProgramm ein Textbereich vom Typ TextArea erstellt. Die Instanz dieser Klasse wirddurch die Anweisung:

�����*�#�;�����#��/�����*�#�;���,M0\M��

erzeugt. Der Konstruktor übernimmt dabei die Zeilenanzahl von 20 Zeilen und dieAnzeigebreite von 60 Spalten. Die Instanz des Programms bzw. Applets ist bereitsbeim Eintritt in die Hauptmethode start() eines Applets vorhanden (im Gegensatz zustatic void main() bei normalen Java-Anwendungen), d.h. es muss nicht erst ein Kon-struktor aufgerufen werden, um eine Instanz der Anwendung zu erzeugen.

Damit ein Textfeld im Browser angezeigt wird, muss dieses dem Applet über dieadd()-Methode, die von der Klasse Applet vererbt wurde, hinzugefügt werden. ZurAusgabe von Text im Browser muss man nun lediglich die TextArea()-Methodeappend() ausführen. Die Methode resize() der Applet-Klasse legt die Größe desApplets explizit auf 500x350 Pixel fest. Der Rest des Programms ist bereits bekannt:Der einzige Unterschied besteht darin, dass die sonst übliche Ausgabe mit Hilfe von

�- ����������������� durch ��#������!��

ersetzt wurde.

Da das Applet auf mehrere Klassen zugreift, ist es empfehlenswert, diese in einemArchiv zusammenzufassen. Dies kann für das vorliegende Beispiel über die Anwei-sung

�������%')�O������;��������8��� O')8��� ��� %')�O������;��������

geschehen.

Sollte das Applet nicht funktionieren, so können Fehlermeldungen über die Anzeigeder Java-Konsole leichter gefunden werden. Diese Option wird von jedem Browserunterstützt. Das Dienstprogramm Appletviewer aus dem JDK gibt eventuelle Fehler-meldungen dagegen in einem Konsolen-Fenster aus.

Beispiel 4.23 zeigt das HTML-Quellprogramm, das das Applet in Beispiel 4.22 aufruft.

Page 166: Java in Datenbanksystemen

�// ������������� ��

Beispiel 4.23

4:*+754:";'54*H*7"5�%')��'����;������4(*H*7"54(:";'54)&'[54;227"*��&'"/$������;�������� $�;9�:HT"/$������;�������0�� � F,�>��$�?H'*:/.MM�:"Ha:*/GMM5����!����U������! ������������#!������U��H������#�� � F,�>����U��&����4(;227"*54()&'[54(:*+75

Die Beschreibung der HTML-Quelldateien bzw. HTML-Tags gehört nicht zu Themendieses Buches. Aus diesem Grund werden wir nur das APPLET-Tag des Beispiels 4.23erörtern.

Die Angabe CODE des APPLET-Tags gibt die auszuführende Klasse mit dem vollstän-digen Pfadnamen an. Die optionale Angabe ARCHIVE gibt die Bibliotheken allerbenötigten Java-Klassen, durch Komma getrennt, an. Für das jeweilige Datenbanksys-tem müssen die entsprechenden JDBC-Treiber-Bibliotheken angegeben werden, fallsdiese nicht im Klassenpfad liegen. Die Angaben WIDTH und HEIGHT sind unbedingtnötig, damit ein graphischer Kontext für das Applet erzeugt wird und die Größe desAppletbereichs explizit festgelegt wird.

Mit Hilfe des Dienstprogramms Appletviewer kann unter Angabe der HTML-Dateidas Applet genau wie im Browser getestet werden.

�������

Durch die Sicherheitsrestriktionen bei Applets darf nur auf Klassen aus demselbenVerzeichnis zugegriffen werden, aus denen das Applet gestartet wurde. Deswegenmüssen die angegebenen Archive im gleichen Verzeichnis auf dem Web-Server lie-gen. Die URL-Angabe der Datenbank muss deswegen mit der URL-Angabe desApplets übereinstimmen. Aus diesem Grund wird die Verbindung nicht funk-tionieren, falls die Datenbank über eine IP-Adresse angesprochen wird, das Appletaber von localhost gestartet wird. Wird aber das Applet über dieselbe IP-Adressewie die Datenbank aufgerufen, wird die Datenbankverbindung funktionieren.

Page 167: Java in Datenbanksystemen

<�(=��>�?�+�������� � �/4

���J X�!R��1�2� ���������

Die großen Objekte (large objects – LOB) weisen eine praktisch uneingeschränkte Größeauf und ermöglichen damit die Speicherung solcher Objekte wie Binärdateien, Bilderoder Unicode-Texte in einer Tabellenspalte. Für große Objekte stehen bei SQL zweiDatentypen zur Verfügung:

� große textuelle Objekte namens CLOB (Character Large Object)

� große binäre Objekte namens BLOB (Binary Large Object)

Der Datentyp CLOB speichert sehr große Textdateien (gewöhnlich bis zu einer Größevon 4GB). BLOB entspricht dem Datentyp CLOB, speichert aber beliebige binäre Daten(wie z.B. Bilder).

Bei manchen Datenbanksystemen existieren auch weitere, nicht standardisierte Daten-typen (wie RAW und LONG RAW bei Oracle bzw. TEXT und BYTE bei Informix), indenen ebenfalls Daten bis zu 4GB Länge gespeichert werden können. Aufgrund derKompatibilität mit anderen Datenbanksystemen wird jedoch empfohlen, alle großenObjekte mit Hilfe der standardisierten Datentypen CLOB und BLOB zu definieren.

Das folgende Beispiel erlaubt die Speicherung beliebiger Bilddateien in einer Daten-banktabelle. In der Tabelle wird der Ursprungspfad der Datei als großes textuellesObjekt (CLOB), die Datei selbst als großes binäres Objekt (BLOB) gespeichert. Als ein-deutige Identifikationsnummer dient eine Spalte mit einer Bildbeschreibung. Das Bei-spiel überprüft zuerst, ob eine Datei gespeichert werden soll und danach, ob eine Dateiim Ursprungsverzeichnis wiederhergestellt werden soll. Optional kann der Inhalt derDatei direkt oder in hexadezimaler Form ausgegeben werden.

�������

Oracle unterstützt zusätzlich noch den Datentyp BFILE, der es erlaubt LOB-Dateienaußerhalb der Datenbank zu speichern. (Generell ist immer zu empfehlen, größereDatenmengen nicht direkt in einer Datenbank abzulegen, sondern nur den Pfad aufdie Datei in einem freigegebenen Ordner in der Datenbank zu speichern.)

�������

Die Methoden dumpBlob() und restorePic() sollten sich direkt auf andere JDBCAPI 2.0 unterstützende Datenbanksysteme wie DB2 übertragen lassen, da dortlediglich JDBC-Klassen verwendet werden. Die Änderung eines Objektes vom TypBLOB hingegen, die wir mit der Oracle-spezifischen Methode storePic() demon-striert haben, wird bei jedem Datenbanksystem anders behandelt.

Page 168: Java in Datenbanksystemen

�/� ������������� ��

Beispiel 4.24

��1���%')���������8��� �������������������������� �����((��U���7&)���!�)7&)������������� ������������������!���!����������������� �7��C���� ��������������')+��/�')8��� �&9;�7"�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//������������������������-��������C���������������� ��;������������ ��������������� ����/����������������������������������- ����������������$)��! ��������������'�����1���������������/�����$���������������- ����������������$T�����!����>��')�&IO�$���������������- ����������������$)��!������')� ���������(��_$�������������������!7���������� �$$������������������ ����2������������������- ����������������$)��!���� �')����������������!����� �������(��_$����������������������������/���!7���������������������K����������� �$$����- �����#���M���������������� ����2�����������������((;� ���� ������������������������������������������������������ ������������E��������((;� �U��������%')�� ���������!����3���������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O����� ���������������������O�$������������������������1*������

ORACLE

Page 169: Java in Datenbanksystemen

<�(=��>�?�+�������� � �/!

��������E����E(("�!������+������������� ��������������!7�����C����������-C�����������������������)������!9�!�������������������H���������9�!����- �����������!7��������������E�����"#����������CE���������������$$�����E����((�)������!������'����� �')��� ������������� ��������!��� ����2���������� ��67"#�������0�����H&"#�������0� ������ ���!"#�������C�����������������������)��������������� �/� �����#�����6���-�$ ��������������������$���������� ���&��������������������������������0������������������� ���#����C����������������/�� �����������F�����������������������/�� ���������,����������������/�� ����)����G������������������/����������������F0������������������������������- ����������������$)��!�$P���P$�����$P���P$������������� ���������(��_$���������������������������/���!7���������������������K���������� �$$������������������������������������������/����� ���&������������������������������������������)-�� �F0�������������������������������������� �����������������- ����������������$;� ����� �:"Q�'����(��_$��������������������/���!7������������������������������� �$$�������������������- ����������������$:�#�'���3�$P!���)�����0���������������E����E����((�)�������!�7&)�'���� ������������������� ��������!� ����2���������� ��67"#�������0�H&"#�������0�����"#�������C�������� ���H�������������/�����������������������������������������������/$$���������!�C�����������������/�� ���������������- ����������������$)���������������������'������������������������2�!��3$����������������-C����������������������/���!7����������������������������������� �$�$����- �����#���M���������������������/����� ���H�����������������������������E�����"#����������C

Page 170: Java in Datenbanksystemen

�4� ������������� ��

�����������������- ����������������$ �����������7� ���!���'���K$������������������������/������������������E��������E����������������������- ����������������$)��������������������)� �����������3$������������������������/���!7���������������������������� �$�$����- �����#���M����������((�*����������)������!�������� ����������������-C������������ �����#������$�9";*"�*;)7"�����������������������������T;9�:;9�,ZZ�������-�1�-0���������7&)0������)7&)�$����������E�����"#����������CE�������������������/�M���������((�)7&)�7�������� ������3�������� �����#������$H��"9*�H�*&���������T;78"���@$P������P$@0���������@$P�����P$@0����-<��������$����������((�)7&)��U��c�!�������� ����������� �/� �����#�����6���-�$�"7"�*������ 9&+���������?:"9"����������������/�@$P������P$@$����������� ���#������������((�)7&)�� �9� ��������� ��0�&����)7&)��U���� �����D��������������)7&)�����!��/���&����9� �������� �����)7&)�F�����������-��VW��������/������-��V����!���������1��>���W���������������� ��/F������������������������/������!����������K/��F���������C������������((���>���)-�� �����>�������1U�>�����������������������4��������������C�����������������-��VW����/������-��V������W��������������������������/M���4���������PP�����������������������V�W�/�������V�W������������������������/����������������E����������������!�����)-�� ���� ��0����������������������� ��P/���������������E���������- ����������������$)��!��� ��������O�$������E����((�;� �������� �)��� 0�� �:�#'� ���������!���D����������((�&9;�7"� ��>��� ������������� ������������!���)����)��������0����������#��C��������������?������ ��/�����������?������������������-C��������������H������������ �����/���������)���-���������������������-��VW��������/������-��VFMMW������������������������/�M����������������������������/��� �������!����������K/��F�������������C������������������������/M���4���������PP�C�������������������-�����/�������V�W������������������������#�C

Page 171: Java in Datenbanksystemen

<�(=��>�?�+�������� � �4�

����������������������������/����������`�M#������������������������������4�F\�� ��������@M@���������������������� ��������H���������:�#���������������������������E������������������ ��������������������� �������������������������E������������E������������������� ���������������������E�����"#����������CE���������������$$�����EE

Die Ausgabe sieht etwa so aus (je nach eingegebenen Daten):

)��! ��������������'�����1���/�����T�����!����>��')�&I)��!������')� ���������(��_)��!���� �')����!����� �������(��_;� ����� �:"Q�'����(��_

Die im Beispiel zur Änderung eines großen binären Objektes benötigten KlassenOracleResultSet und BLOB werden mit Hilfe der Anweisungen

������������� ������������������!���!��������

importiert. Damit die Datenbank die aktuell veränderte Reihe mit dem großen binärenObjekt bis zum Abschluss der Änderung sperrt, ist die Anweisung

���� ��;������������ ���

nötig, um den AutoCommit-Modus zu deaktivieren.

In der main()-Methode werden Benutzereingaben mit Hilfe der statischen readLine()-Methode verarbeitet, welche eine Zeile vom Bildschirm einliest. Je nach gewählterOption werden dann die Methoden storePic() und restorePic() aufgerufen. DieMethode storePic() ist Oracle-spezifisch, weil sie Instanzen der Oracle-Klasse BLOBverwendet, welche im Gegensatz zu der JDBC-Standardklasse java.sql.Blob Änderun-gen der großen binären Objekte zulässt.

In einer Schleife wird so lange die Eingabe eines Dateinamens verlangt, bis die Dateiüber eine Instanz der Klasse FileInputStream geöffnet wird. Mit Hilfe der SQL-Anwei-sung:

�9";*"�*;)7"�����������������T;9�:;9�,ZZ�������-�1�-0���������7&)0������)7&)�

wird versucht, die Tabelle zu erzeugen, falls diese noch nicht vorhanden ist. Um eingroßes binäres Objekt in der Datenbank zu speichern, reicht es nicht, einer INSERT-Anweisung einfach ein solches Objekt direkt zu übergeben. Bevor ein solches Objekt

Page 172: Java in Datenbanksystemen

�4" ������������� ��

verändert werden darf, muss ein so genannter Lokator in der Datenbank abgelegt wer-den, der einen Bezug zwischen dem Spaltenwert und der Instanz der Klasse Blob her-stellt. Bei Eintragung von sehr kurzen Daten in einer Instanz der Klasse Clob bzw.Blob können diese jedoch direkt in der INSERT-Anweisung übergeben werden. (Beieiner Instanz der Klasse Clob wird eine alphanumerische Zeichenkette und bei einerInstanz der Klasse Blob eine Zeichenkette in der hexadezimalen Form ausgegeben.)

Für eine nachträgliche Änderung muss vorher explizit ein Lokator erzeugt werden. BeiOracle geschieht dies durch die Funktion empty_blob(). Mit Hilfe der Anweisung:

�����#������$H��"9*�H�*&���������T;78"���@$P������P$@0�@$P�����P$@0����-<��������$��

wird der Bildname und der Bildpfad bereits in der Tabelle eingetragen. Der Bildpfadist dabei innerhalb der Anweisung in Anführungszeichen angegeben und wird alsInstanz der Klasse Clob gespeichert. Die Methode empty_blob() erzeugt für eineBlob-Instanz einen Lokator.

Für eine Instanz der Klasse Clob ist die Anweisung empty_clob() erforderlich. MitHilfe von:

� �/� �����#�����6���-�$�"7"�*������ 9&+���������?:"9"��������/�@$P������P$@$��

wird dieser Lokator aus der Datenbank in eine Instanz der Schnittstelle ResultSet gele-sen und kann danach verändert werden. Da eine Instanz der Standardklassejava.sql.Blob normalerweise nicht geändert werden kann, muss man hier die Oracle-spezifische Klasse OracleResultSet verwenden und die Blob-Instanz in eine BLOB-Instanz umwandeln, um diese beschreiben zu können. (Die Klasse BLOB stellt dieOracle-spezifische Implementierung eines großen binären Objektes dar, während dieKlasse java.sql.Blob die JDBC-Standardimplementierung desselben Objektes zeigt.)Die Instanzänderung geschieht mit Hilfe von:

)7&)�����!��/���&����9� �������� �����)7&)�F���

Die Oracle-Klasse BLOB unterstützt mehrere in Standard-JDBC nicht existierendeMethoden, unter anderem getChunkSize() und putBytes(). Die Methode getChunk-Size() erlaubt es, die optimale Datenblockgröße für das Lesen des großen binärenObjektes bzw. Schreiben in das große binäre-Objekt zu ermitteln. Die Methode putBy-tes() erlaubt es, Datenblöcke ab einer bestimmten Stelle (offset) in der BLOB-Instanz zuschreiben. Durch die Verwendung der optimalen Blockgröße kann die Schreib-/Lese-Performance auf die großen Objekte erhöht werden.

Zum Wiederherstellen von gespeicherten großen Objekten (textuellen oder binären)wird die Methode restorePic() verwendet. Über eine Instanz der ResultSet-Schnitt-stelle werden die einzelnen Spalten aus der Tabelle gelesen, und über die getClob()-und getBlob()-Methoden werden die Daten aus den großen Objekten gelesen. Die

Page 173: Java in Datenbanksystemen

�� ������$�����+(��� �4*

Clob-Schnittstelle (java.sql.Clob) unterstützt zum Lesen unter anderem die Methodenlength() und getSubString(), während die Blob-Schnittstelle (java.sql.Blob) dieMethoden length() und getBytes() enthält, um die Daten zu lesen. Die Instanzen derKlasse Blob werden im Beispiel über eine Instanz der Klasse FileOutputStream in dieUrsprungsdatei, die als eine Instanz der Klasse Clob definiert ist, geschrieben. DieMethode sollte mit allen Datenbanksystemen, die die Schnittstellen Clob und Blob mitihren JDBC-Treibern unterstützen, auf die gezeigte Weise funktionieren.

Optional können die Instanzen der Klasse Blob im Beispiel am Bildschirm ausgegebenwerden. Dies wird mit Hilfe der Methode dumbBlob() durchgeführt. Diese Methodeübernimmt als Parameter ein großes binäres Objekt und liest über die getBinary-Stream()-Methode der Blob-Klasse aus deren InputStream die Daten sequenziell aus.Die Daten werden je nach angegebener Option in hexadezimale Form umgewandeltoder direkt geschrieben. Am Schluss wird die Zeichenkette, die direkt mit Hilfe einerInstanz der Klasse StringWriter ausgegeben wird, zurückgegeben. (Die in Beispiel 4.21verwendete Methodik ist sehr allgemein gehalten und nicht datenbankspezifisch.)

���� ������������� ��!���

Eine Datenbank wird in der Regel von mehreren Anwendern gleichzeitig benutzt. Die-ser Umstand wirft eine Reihe von Problemen auf, die alle mit völliger Korrektheitabgehandelt werden müssen. Der konkurrierende Datenzugriff mehrerer Benutzermuss bei jedem Datenbanksystem gewährleistet sein.

Ein weiteres Problem, mit dem ein Datenbanksystem konfrontiert ist, sind Fehler, diesowohl in der Software als auch in der Hardware auftreten können. Ein Datenbank-system sollte in der Lage sein, nach denkbaren Ausfällen die betroffenen Datenbankenin den letzten konsistenten Zustand zu überführen. Sowohl der konkurrierende Daten-zugriff mehrerer Benutzer als auch die Erhaltung der Konsistenz der Datenbankennach einem Hardware- oder Softwareausfall wird mit Hilfe der Transaktionen gewähr-leistet.

������ ����������

Eine Transaktion kennzeichnet mehrere nacheinander folgende, logisch zusammen-hängende Anweisungen. Um die Datenbank im konsistenten Zustand zu halten, mussjede Transaktion entweder vollkommen ausgeführt oder zurückgesetzt werden. Uminnerhalb einer Transaktion entscheiden zu können, ob die Transaktion ausgeführtoder zurückgesetzt werden soll, ist es notwendig, alle geänderten Reihen in ihrerursprünglichen Form zu protokollieren. Für die Speicherung dieser Werte wird beiallen Datenbanksystemen das Transaktionsprotokoll verwendet. Ein Transaktionspro-tokoll kann system- oder datenbankbezogen sein. Mit anderen Worten, bei manchen

Page 174: Java in Datenbanksystemen

�4� ������������� ��

Datenbanksystemen werden alle Datenbanken gemeinsam in einem Protokoll gespei-chert, während andere je ein Transaktionsprotokoll für jede Datenbank verwalten.

Jedes Datenbanksystem unterstützt zwei Arten von Transaktionen:

� implizite

� explizite.

Explizite Transaktionen enthalten SQL-Anweisungen in Bezug auf Transaktionen wieCOMMIT und ROLLBACK. Die COMMIT-Anweisung beendet erfolgreich die voran-gehende Transaktion und startet gleichzeitig die nächste. Mit der ROLLBACK-Anwei-sung werden alle schon ausgeführten Anweisungen der gestarteten Transaktionrückgängig gemacht.

Bei impliziten Transaktionen wird jede Anweisung (implizit) als eine einzelne Trans-aktion behandelt.

������ ������*��)!����(!%%��NO������!����( NO

Das Transaktionsverhalten der Datenbank wird mit Hilfe einer Instanz der Klasse Con-nection gesteuert. Diese Klasse hat zwei Methoden:

� void commit( ) throws SQLException;

� void rollback( ) throws SQLException;

die in Bezug zu Transaktionen stehen.

Diese Methoden entsprechen den oben beschriebenen SQL-Anweisungen COMMITund ROLLBACK. Mit der Methode commit() wird also die aktive Transaktion erfolg-reich abgeschlossen und die nächste gestartet. Genauso werden alle ausgeführtenAnweisungen der aktiven Transaktion mit der Methode rollback() rückgängig gemacht.

JDBC unterstützt eine weitere Methode – setAutoCommit() –, die darüber entscheidet,ob eine Anwendung implizite oder explizite Transaktionen verwendet. Nach dem Her-stellen einer JDBC-Verbindung befindet sich jede Datenbank, gemäß der JDBC-Spezifi-kation, zunächst in dem sogenannten AutoCommit-Modus. Der AutoCommit-Modusbedeutet, dass der Parameter der Methode setAutoCommit() der Klasse Connectionauf richtig (true) gesetzt ist und damit jede einzelne Anweisung als separate Trans-aktion behandelt wird (impliziter Modus).

Durch den Aufruf der setAutoCommit()-Methode und die Übergabe des Wertes falsekann das geändert werden. Danach müssen alle Transaktionen explizit durch den Auf-ruf der Methode commit() bestätigt bzw. durch die Methode rollback() zurückgesetztwerden. Mit Hilfe der Methode getAutoCommit() und ihres Rückgabewertes ist esmöglich, den AutoCommit-Modus der Anwendung zu ermitteln.

Page 175: Java in Datenbanksystemen

�� ������$�����+(��� �4.

Die Verwendung eines der beiden Modi kann signifikante Folgen für die Performanceeines JDBC-Programms haben. Aus diesem Grund ist es wichtig zu wissen, welcherModus performanter ist als der andere. Dieses Thema wird ausführlich in Kapitel 6behandelt.

Folgendes Beispiel zeigt ein JDBC-Programm, das zwei UPDATE-Anweisungen inner-halb einer Transaktion ausführt.

Beispiel 4.25

��������� ������������8��� ����� �*�� 1����C���� ��������������')+��/�')8��� �H� &9+HQ�����((���S������T��������U��')�D������������� ��������������������/���������� �������������� ����/���������� �����9� �������� �/����������((������������������������������������������������ ��������!���������������VW�����C������������K')8��� �����'�� �'������')+����������������������������/�')8��� ��������'�) ��')+����//��������������

����������-��������C�������������- ����������������$T�����!����>��')�&IO�$��������������((;�����������!�1��������3���������������� ��;������������� ���������������� ����/���������������������

������������'�� �+��'��!��!�/��������+��'�����������������- ����������������$����'+7�*�� 1������������ �U�>�3$P�������������!��!� ������ '�+���������*�� ����� &��-������������������- ����������������$''7���!�'+7�*�� 1������������������������ �U�>�3�$P�������������!��!� ������ '�'���������;�!'�+���������*�� ����� ����������������((' ����!�! ������X�����Y��U��'),������!������KKK����������������')+��//�')8��� �'),��� �����#������$�"*��899"�*���������������:"+;�!�,!���$����������������-�C

�������

Beispiel 4.25 kann nicht mit MySQL benutzt werden, weil dieses DatenbanksystemTransaktionen bei JDBC nicht unterstützt.

ORACLE, ORACLE, INFORMIX, DB2

Page 176: Java in Datenbanksystemen

�4/ ������������� ��

�����������������������������������������������(('���������!���;���� ����������������>� ��������������������((����0����I�� � ���>�>���������3���������������� �����#������$82';*"����������"*��<��/FFFFF�?:"9"������������������<��/FMFM,$������������������(('�� ��;���� ������>����������"#�������3���������������� �����#������$82';*"�������������"*��<��/FFFFF�����������������?:"9"� �<��/FMFM,$������������������((��������!������!��;���� ������� ���U���3�����������������������������������������E��������67"#���������1 ��C�����������������- ����������������$O� ���������*�� 1���� �)���10�����������������9�����1����!�� ���U���$����������������������������1���������������E������������((;� ���� ���������������������������������������������������� ������� ����������������������� ������������E��������((;� �U��������%')�� ���������!����3����������������������������((�����67�+����!����������������������67"#���������������������67"#������������������C������������')8��� � ����67"#�������������������E�������������"#����������C�������������- ����������������$O�����8���1������ ���������O�$������������������������1*��������������E����E(("�!������+��E

Die Ausgabe des Beispiels 4.25 sieht folgendermaßen aus:

T�����!����>��')�&I����'+7�*�� 1������������ �U�>�3��� �''7���!�'+7�*�� 1������������ �U�>�3����� ���������*�� 1���� �)���10�9�����1����!�� ���U���

Am Anfang des Beispiels 4.25 wird der AutoCommit-Modus deaktiviert und mit Hilfeder Methoden supportsDataManipulationTransactionsOnly() und supportsDataDefinitionAndManipulationTransactions() überprüft, ob der Treiber Transaktionenausschließlich mit DDL-Anweisungen unterstützt, oder ob beide Anweisungsarten(DDL und DML) in Transaktionen vorkommen können.

Die beiden UPDATE-Anweisungen, die im try-Block existieren, sollen (wegen der refe-renziellen Integrität) entweder beide ausgeführt oder beide zurückgesetzt werden.Damit wir die Ausführung der rollback()-Methode zeigen (und damit das Zurückset-zen der Ausführung beider Anweisungen), haben wir einen syntaktischen Fehler indie zweite UPDATE-Anweisung eingebaut. Aus diesem Grund wird das Zurücksetzenbeider Anweisungen ausgeführt.

Page 177: Java in Datenbanksystemen

�� ������$�����+(��� �44

�����D ��!�����������$��

Die Isolierungsstufen stellen auf verschiedenen Ebenen dar, wie sicher ein Benutzersein kann, dass die von ihm gelesenen Reihen den aktuellen Inhalt haben. Sie stehenim Zusammenhang mit den Sperren, die für Leseoperationen gesetzt werden.

Der SQL-Standard unterstützt vier Isolierungsstufen:

� READ UNCOMMITTED

� READ COMMITTED

� REPEATABLE READ

� SERIALIZABLE.

READ UNCOMMITTED kennzeichnet die niedrigste Isolierungsstufe; dabei wirdbeim Lesen eines Objektes keine Sperre vom Prozess gesetzt, d.h. es wird nicht über-prüft, ob schon irgendeine Sperre auf dieses Objekt existiert. Bei READ COMMITTEDwird festgestellt, ob eine Sperre beim Lesen des Objektes möglich ist. (Bei dieser Isolie-rungsstufe setzt das System keine Sperre; vielmehr wird überprüft, ob eine solcheSperre gesetzt werden kann.)

READ REPEATABLE setzt eine Lesesperre auf eine Reihe, während sie gelesen wird.(Nach dem Lesen wird die Sperre aufgehoben.) Bei der Isolierungsstufe SERIALIZABLEwerden Sperren auf alle Reihen gesetzt, die zum Ergebnis einer Abfrage gehören. DieseSperren werden so lange gehalten, bis die Transaktion, zu der die Abfrage gehört, been-det wird.

In Bezug zu Isolierungsstufen unterstützt die Connection-Schnittstelle fünf Konstan-ten:

� TRANSACTION_NONE

� TRANSACTION_READ_UNCOMMITTED

� TRANSACTION_READ_COMMITTED

� TRANSACTION_REPEATABLE_READ

� TRANSACTION_SERIALIZABLE.

�������

Je höher die Stufe der Isolierung desto weniger Konsistenzprobleme können durchgleichzeitigen Zugriff mehrerer Transaktionen auf dieselben Daten entstehen.Andererseits ist der Durchsatz bei einer großen Anzahl von gleichzeitigen Zugrif-fen geringer.

Page 178: Java in Datenbanksystemen

�4� ������������� ��

Diese Konstanten werden mit der entsprechenden Methode benutzt, um die Isolie-rungsstufe einer Anwendung festzulegen. (Die Konstante TRANSACTION_NONEspezifiziert, dass Transaktionen für die aktuelle Datenbank nicht verwendet werden.)

Mit Hilfe der beiden Methoden getTransactionIsolation() und setTransactionIsola-tion�� der Connection-Schnittstelle kann die aktuelle Isolierungsstufe abgefragt, bzw.verändert werden. Mit der Methode supportsTransactionIsolationLevel() der Data-baseMetaData-Klasse kann abgefragt werden, ob ein Datenbanksystem eine bestimmteIsolierungsstufe unterstützt oder nicht.

���� �:#�%G��������"G��()���-H'�������3�

Wie bei jeder Schnittstelle zwischen zwei Sprachen, ist es auch bei SQL und Java not-wendig, die Datentypen der ersten in die Datentypen der zweiten Sprache (und umge-kehrt) zu konvertieren. Dies ist bei SQL und Java unbedingt notwendig, weil esteilweise sehr große Unterschiede bei den Datentypen zwischen verschiedenen Daten-banksystemen gibt.

JDBC verwendet die Klasse java.sql.Types, um die SQL-Datentypen abzubilden. Jedesstatic-Feld dieser Klasse stellt einen SQL-Datentyp dar. (Die Klasse enthält keineMethoden.) Die Umsetzung eines SQL-Datentyps in einen entsprechenden Java-Daten-typ wird dann vom Treiber automatisch durchgeführt.

Die tatsächliche Umwandlung geschieht beim Aufruf der Methoden getXXX() bzw.setXXX(). getXXX() ist der generische Name für alle Methoden der ResultSet-Klasse,die die einzelnen Spaltenwerte der aktuellen Reihe holen. Damit kann man mit dengetXXX()-Methoden SQL-Datentypen lesen und in enstprechende Java-Datentypenumwandeln. Genauso kann man setXXX()-Methoden der Klasse verwenden, um Java-Datentypen in entsprechende SQL-Datentypen zu konvertieren und Werte danachzurückzuschreiben. (In der Klasse CallableStatement existiert auch eine Methodenamens registerOutParameter(), die die Umwandlung des Datentyps der Ausgabe-parameter einer gespeicherten Prozedur vornimmt.)

Die einzige Ausnahme zu der obigen Beschreibung stellt die Verwendung der CREATETABLE-Anweisung dar. In diesem Fall werden die SQL-Datentypen für Tabellenspal-ten benötigt. Die Information darüber kann mit Hilfe der getTypeInfo()-Methode derDatabaseMetaData-Klasse ermittelt werden.

Tabelle 4.4 zeigt die Abbildung von SQL-Datentypen auf Java-Datentypen.

Page 179: Java in Datenbanksystemen

8���))��������� �4!

���D U���%%��$������

JDBC ist eine der beiden Java-Schnittstellen, die für Datenbankprogrammierung ver-wendet werden können. Im Unterschied zu einer ähnlichen Schnittstelle wie ODBChat JDBC viele Vorteile, u.a. Objektorientiertheit und Robustheit (weil sie Java-Aus-nahmeklassen verwendet).

Die Auswahl des Treibers kann für die Verwendung und die Performance einer JDBC-Anwendung sehr wichtig sein. Es ist empfehlenswert, einen Treiber vom Typ 4 (nativeJDBC-Treiber) zu wählen, weil sie eine direkte Verbindung zur Datenbank herstellenund damit eine sehr effiziente Lösung für den Einsatz im Internet bieten.

Das nächste Kapitel beschreibt, wie die objektorientierten Erweiterungen mit JDBCimplementiert werden können.

������������ ��������

�M�= -�����

?�=�M�= -�����

<F*�=�� 2�3��%��)�����(�%��

���*�' 2�3��%��)�����(�%��

�� �!!����

��<Y�<� �:��

-*�''�<� �)!��

�<��X�= ���

�X�<� �!��

=��' $�!��

,'1�� �!����

1F'� �!����

�<�=Y �:��KL

?�=�<�=Y �:��KL

��� 2�3���;�����

��*� 2�3���;����%�

��*�-��*� 2�3���;����%����%#

$����������������������(��0:�#����%&�����������#����%&��

Page 180: Java in Datenbanksystemen
Page 181: Java in Datenbanksystemen

� ���������� ���� ��� �� ���� �� ���� �

Nachdem wir in Kapitel 2 die objektorientierten Erweiterungen in den Systemen Infor-mix, Oracle und (nur skizzenhaft) IBM DB2 vorgestellt haben, werden wir in diesemKapitel, auf der Basis dieser Erweiterungen, die entsprechenden JDBC-Erweiterungenvorstellen. Weil dieses Kapitel dieselben (objektorientierten) Inhalte wie Kapitel 2 hat,wird seine Struktur der Struktur des Kapitels 2 entsprechen: Im ersten Teil werden dieobjektorientierten Erweiterungen in Oracle mit Hilfe von JDBC dargestellt, währendder zweite Teil JDBC-Programme mit Informix-spezifischen Erweiterungen enthält.(Einen Abschnitt über DB2 gibt es nicht, weil die Firma IBM objektorientierte Erweite-rungen für JDBC noch nicht implementiert hat.)

��� ���������� ���� ��� �� ���� �� ���� ��� �������

Oracle hat folgende Erweiterungen, die in Bezug zur Objektorientierung stehen:

� der Objekttyp

� der Datentyp REF (Objektreferenzen)

� Kollektionen (Vektoren und geschachtelte Tabellen).

Der Objekttyp und der REF-Datentyp werden in einem Abschnitt dargestellt, währendzwei weitere Abschnitte Kollektionen in Oracle beschreiben.

����� � ����� ��������� ����� ��������

Das folgende Beispiel zeigt die Verwendung des REF-Datentyps und der CREATETYPE-Anweisung.

Beispiel 5.1

������������ ��������������� ����������������

ORACLE

Page 182: Java in Datenbanksystemen

��� ������������ ����� �����������������������

���������������������������� ��������!���������������� ����������������"������������#�������"��������!���������������$���������� ����������������%�&��$� ������'��()����������(�������� *+"�,� *�������-./ ������$��0��1���2����$���(��� *�3�1��((�������������-��������������,��� ����������"�������������,��� ��������������"�����,��� �������������������������������������������������$������������������4"����1���1�567����)���������(4�8 *�������� ���$�� �����4 *+"77������� ���������(4�4����,� *����������� ���*��4 *+"77�,,���7������� �������������������)������������"���������������492��$�����1�:�� *��;<�97 ���������������=�1���>������1����������/�1�$�����1������������������������# �?�*./�-������0��1����������������,����������������������"��������4����"���?�#/'"-��..'"/@"A?A2/B����������������"���-�@-��'�# �?�*./7 ����������������������?�$�������?���0�&�����������������)���������������������C������49 ��#�?�*./���$�����D97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�*./������G�D97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�*./������$�����D97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�#/���$�����'���97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�#/������G�'���97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�#/������$�����'���97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������?�$��������?����������������������������C�����49-�/�?/�?�#/������$�����'�����"��*H/-?�������������4�'������B��'������&��4IJ7B��������������'���������&��4IJ7B��$�'����&��4IJ7797 ������������"���������������49�����$�����'���������97 �����������������C�����49-�/�?/�?�#/������G�'�����"��*H/-?��4��'����������������&��4K7B���'������&��4IL7B�������(���4DIM7797

Page 183: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

������������"���������������49�����G�'���������97 �����������������C�����49-�/�?/�?�#/���$�����'�����"��*H/-?�4�'���������������A@?B���'���-%��4K7B���(1�$��-%��4IL7B�����'���� �?/B���������������$'�����/�������$�����'���B���$'�����/�������G�'���797 ������������"���������������49��$�����'���������97 �����������������C�����49-�/�?/�?�*./������$�����D���������������������$�����'���97 ������������"���������������49�����$�����D������97 �����������������C�����49-�/�?/�?�*./������G�D���������G�'���97 ������������"���������������49�����G�D������97 �����������������C�����49-�/�?/�?�*./���$�����D������$�����'���97 ������������"���������������49��$�����D������<�97 ��������������� ��������(�1��������������"���������������4�����C�����������49����������������������������$�����D4�'��B��'����B��'�������B��$�'��7��������������������(���������$�����97�N9����&������1�(�1�97 ������������"���������������4�����C�����������49����������������������������G�D4��'��B���'����B������7��������������������(���������G�97�N9����&������1�(�1�97 ������������"���������������4�����C�����������49�������������������������$�����D4�'��B���'��B���(1�$�B�����'���B���������������$'���B���$'���7���������'��B����'��B����(1�$�B�������'���B���������������(4�7B���(4�7�(������$�������B������G�D��B������$�����D���=&�������������������'���,����'�����������'���,�����'��97�N9����&������1�(�1�<�97 ����������������$(��1������%�(������/�� ���������������������,������C�����F����49"/./-?�����(1�$�B�����������������$'�����'����B�����$'���������B�����$'�������+���������������$�����D����O%/�/�����'����P�QD�D�DRSSQ97 ���������������?���+���?�$���������B��������*����:����(�����������������������?�����(������;����$:�$�������������������=������������(��������/��1��2����+��&����$��0��1�������������%�&��$����=+���,���=�%�&��$�47 ��������������=+������49"-�??�+A?��*/A?/�'?�#9B������������-��(��@���49��$'���977 ���������������������&�����1�$��B������������T�����������������=&��4����C�477)�����������������������/���$��G������������H *-����G�������������������������/����(�,�4�/�7���1���$�����4K7 ����������������������������/���$��G���������-./����G�����������������������������(�,�44���������"��7�7�1���/�4D7 ���������������������"U�*/!������������������������������������������������������������O������������/��&�����������"?��-?�������������������������"?��-?��������&���������-./��$��G����������������������"?��-?���$������,�4"?��-?7���(�1��2����47 ���������������������1�$������O���������"�����B�G��G���������������������������������:�����"���������+����$������?�������������������$����������$���56�,���$������1�������$���47 ����������������"���������������4997 ����������������(���4�����,J ��V�����$������1�& ��NN7������������������������"��������������4�����$���5�6N9<�97 ����������������"���������������4997

Page 184: Java in Datenbanksystemen

��� ������������ ����� �����������������������

�������������������>@ /��@U!�����������������������������������������������������������+�������������?��������1��������������������������"?��-?��$��G�������$����:����(���������$��G��������������������B�������$��G��G����1�T����������=�����������������������������/��:����G1��&���$���=�����������������������$'������,�4��$'���7���(�1��2���4��=+��7 �����������������(4���'���������47�����49+�:��977)������������������������$��G��T����������������������������'����,9+���9 ������������������������/���$��G������H�2���$��G���$���&���$������������������������(���2���4�7 ������������������������# �?/���(�&���!��������������������#�������"��������������,��������������������������������"��������49�# �?/���$�����D���������������������"/?���$'����,�W�O%/�/��'��,9N���'��7 ��������������������44�����#�������"��������7����7����/�4DB���(7 ��������������������������C�����47 ��������������������"���������������4�����1��������-����47N9������������������������&�4�7��G��������97 ������������������������(��&��=47 ����������������E������������E���������������$�&���$�������������������������������������������������������47 �������������������47 ��������E�������������(�&���&��H *-���&��$�&�����1!���������������������������"F.�+��&�����=��(�������������"F./C�������������������&4"F./C���������7��������)������������ *����&�="F./C�������4�7 ��������E������������&4/C���������7)������������"���������������49<�������&������1�����������<�97 �������������������"���G?����47 ��������E����E������/��������+���E��$��������$'�������������"F. ���)�����$��������'�� �����$���"����1��'���� �����$���"����1��'������� �����$���"����1��$�'�� �����������"����1����@��� ������U�$��������..�F��.A�A/ �@��������"F.�$����:����(��������������?�����=�����B�����������$��G������T������������$���"����1�1��"F.?���@���47)����������������@��� ���E�����$������������"F.4"F.A����������B�"����1�����@���7�)

Page 185: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

����������@����,�����@��� ������������1�$�B�����������&���&�=���B�=���������+��&���������������(1���(���=������������"���������������49G������������������$��G�����&�H�2�97 ������������)��������������'���,�����������A��47 ��������������'�����,�����������"����147 ��������������'��������,�����������"����147 ��������������$�'���,�����������"����147 ���������E����&4/C���������7)E����E�����$��������=����"F.4"F.������������7�)��������������1�$�B�����������&���&�=���B�=���������+��&�����������������(1���(���=������������"���������������49G�����������H�2���$��G�����&������97 ������������)�������������������=����A��4�'��7 �������������������=����"����14�'����7 �������������������=����"����14�'�������7 �������������������=����"����14�$�'��7 ���������E����&4/C���������7)E�����EE

Der Ausschnitt der Ausgabe des Beispiels 5.1 sieht folgendermaßen aus:

2��$�����1�:�� *��;�����$�����'��������������G�'�����������$�����'��������������$�����D�����������G�D��������$�����D������X����&������1�(�1�Y����&������1�(�1�DD����&������1�(�1�RJYD����+������������������������������������������������IG������������������$��G�����&�H�2�DJDJI���%�$���������������������#������������������������YG������������������$��G�����&�H�2�RJYD����+������������������������������������������������IG������������������$��G�����&�H�2�

Zu Beginn des Programms in Beispiel 5.1 werden mit Hilfe der import-Anweisung dieOracle-spezifischen Pakete eingebunden. Für obiges Beispiel sind dies oracle.sql undoracle.jdbc.driver. Das Paket oracle.sql enthält die Oracle-Implementierungen der inJDBC API 2.0 spezifizierten Schnittstellen aus dem javax.sql-Paket. Dies sind z.B. REF,STRUCT und ARRAY. Das Paket oracle.jdbc.driver enthält u.a. die Klassen OracleRe-sultSet und OraclePreparedStatement., die etwa den JDBC-Klassen ResultSet undPreparedStatement entsprechen.

Page 186: Java in Datenbanksystemen

��� ������������ ����� �����������������������

Nachdem die Datenbankverbindung hergestellt wurde, wird zuerst eine Statement-Instanz (stmt) erzeugt, welche wegen der eventuellen späteren Änderungen mit demParameterwert ResultSet.CONCUR_UPDATABLE deklariert ist. (Für die Erläuterungder CONCUR_UPDATABLE-Angabe siehe die Beschreibung des Parameters result-SetConcurrency in Kapitel 4.)

Für eine mehrfache Ausführung des Beispiels werden alle erstellten Datentypen undTabellen, die eventuell noch in der Datenbank vorhanden sind, gelöscht. Falls dabei einFehler auftritt, weil der Typ oder die Tabelle nicht vorhanden sind, wird dies in einemtry/catch-Block, der jede DROP-Anweisung umgibt, abgefangen. Die MethodeshowSQLException() der Klasse DBUtils zeigt dabei die eventuell aufgetretenen Feh-ler an. (Normalerweise entstehen hier für unterschiedliche Datenbanksysteme ver-schiedene Fehler, die man dann explizit abfragen kann.)

Danach werden die für die Übung benötigten Typen, Tabellen und Daten erstellt bzw.eingefügt. Das vorliegende JDBC-Programm lehnt sich dabei an die in Kapitel 2 ver-wendeten Beispiele an. Zu beachten ist hierbei, dass die Typen in der Reihenfolge vomallgemeinen bis zum speziellsten erstellt werden müssen. (Entsprechend muss beimLöschen von dem speziellsten bis hin zum allgemeinsten Typen gelöscht werden, umkeine Fehlermeldungen des Datenbanksystems zu verursachen.)

Mit Hilfe einer Hash-Tabelle wird eine Java-Instanz (Klasse arb_mit), welche dem Typmitarbeiter_typ entspricht, dem Datenbanktyp SCOTT.MITARBEITER_TYP zugewie-sen. Dadurch erfährt Java, wie es den REF-Datentyp genau übersetzen kann. (Inner-halb der Hash-Tabelle kann die Referenz über den SQL-Datentyp den passenden Java-Datentyp finden.) Oracle verlangt dabei, dass Objekttypen mit Großbuchstaben ange-geben werden müssen, da sie auch in der Datenbank so abgelegt sind. Mit Hilfe derMethode getObject() wird die REF-Instanz der SELECT-Anweisung gelesen. Da wirwissen, dass es sich hierbei um einen REF-Datentyp handelt, können wir ihn auchgleich auf den Oracle-REF-Typ abbilden. (Alternativ könnte man hier auch die Instanzder ResultSet-Klasse auf eine Instanz der OracleResultSet-Klasse umwandeln, ummit der dort verfügbaren Methode getREF() direkt das REF-Objekt zu lesen.)

Um an die eigentlichen Daten des REF-Objektes zu gelangen, wird mit der MethodegetValue() der Inhalt des Objektes gelesen und zu einem allgemeineren Objekttypen,STRUCT umgewandelt. STRUCT entspricht der Oracle-Implementierung der JDBC 2.0Schnittstelle namens Struct, die die Java-Standardabbildung für eine SQL-Strukturdarstellt. Die Methode getAttributes() der gelesenen Struktur liefert alle Objekte, diedieses Objekt enthält. In der for-Schleife werden dann diese zur Kontrolle noch einmalausgegeben.

Mit den Mitteln, die wir bis jetzt in Beispiel 5.1 verwendet haben, kann man nur lesendauf den Inhalt des REF-Objektes zugreifen. Um jedoch Werte auch zu verändern,braucht man Mittel, die die passenden Methoden zur Verfügung stellen. In diesem Bei-

Page 187: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

spiel wird dazu ein eigenes Java-Objekt – arb_mit – erstellt, welches den lesenden undschreibenden Zugriff auf die Referenz erlaubt. Jedes Datenbanksystem stellt normaler-weise Werkzeuge zur Verfügung, um derartige Objekte automatisch zu generieren.(Generell kann man dies aber auch leicht selbst machen, indem man einfach nur dieSQLData-Schnittstelle implementiert.) Das Objekt arb_mit stellt also die Java-Reprä-sentation des SQL-Typs mitarbeiter_typ dar. Die drei zu implementierenden Funktio-nen sind:

� readSQL()

� writeSQL()

� getSQLTypeName().

Die Methoden readSQL() und writeSQL() der Schnittstelle SQLData sind für das Ein-lesen, bzw. Zurückschreiben der im Typ enthaltenen Daten zuständig. Dazu liest/schreibt man mittels der im Ein/Ausgabestream vorhandenen Methoden die elemen-taren Datentypen in der Reihenfolge, wie sie im SQL-Typ deklariert wurden. In unse-rem Fall heißt das, dass die Methoden readInt() bzw. writeInt() für die Spalte m_nrund readString() bzw. writeString() für die Spalten m_name, m_vorname und abt_nrangewendet werden. Beide Methoden geben zur besseren Verständlichkeit auch nocheinen erläuternden Text aus, um den Aufrufzeitpunkt zu erkennen. Die Methode read-SQL() erhält außerdem von der Datenbank noch den SQL-Typnamen, den sich dasObjekt als eine String-Instanz merkt. Die Methode getSQLTypeName() gibt dieseInstanz dann auf Anfrage zurück.

Die Anweisung

��$'������,�4��$'���7���(�1��2���4��=+��7

liefert genau das Java-Objekt arb_mit zurück, das mit den aus der Datenbank gelese-nen Werten aktualisiert ist. Mit Hilfe der am Anfang erstellten Hash-Abbildung(Hashmap) wird dabei die korrekte Konvertierung zwischen dem Datenbanktypmitarbeiter_t und dem Java-Objekt arb_mit vorgenommen. Die Methode getValue()erstellt zuerst ein neues Objekt arb_mit und ruft dann mit Hilfe der Methode read-SQL() die SELECT-Anweisung auf, womit alle Daten eingelesen werden.

Im Beispiel wird zuerst nach der Mitarbeiterin namens Mozer gesucht und ihr Nameanschließend in Moser geändert. Dazu wird lesend bzw. schreibend auf die Werte inarb_mit zugegriffen.

Die Programmzeile

��(���2���4�7

ersetzt anschließend die gelesene mit der geänderten Referenz und ruft dazu dieMethode writeSQL() des benutzerdefinierten Java-Objektes auf. Im Beispiel wird eine

Page 188: Java in Datenbanksystemen

��� ������������ ����� �����������������������

Instanz der Klasse PreparedStatement verwendet, um die Änderung der Datenbank-inhalte durchzuführen. Dazu wird diese in eine Instanz der OraclePreparedState-ment-Klasse umgewandelt, damit die Methode setREF() der OraclePreparedState-ment-Klasse aufgerufen werden kann. (Alternativ könnte man hier auch die MethodesetREF() der OracleResultSet-Klasse verwenden.)

����� !��!"#��� ������ �������

Beispiel 5.2 zeigt ein JDBC-Programm mit dem Oracle-Vektortyp.

Beispiel 5.2

������������ ��������������� ���������������� ���������������������������� ��������!���������������� ����������������"������������#�������"��������!���������������$���������� ������'2�����)����������(�������� *+"�,� *�������-./ ������$��0��1���2����$���(��� *�3�1��((�������������-��������������,��� ����������"�������������,��� ��������������"�����,��� �������������������������������������������������$������������������4"����1���1�567����)���������(4�8 *�������� ���$�� �����4 *+"77������� ���������(4�4����,� *����������� ���*��4 *+"77�,,���7������� �������������������)������������"���������������492��$�����1�:�� *��;<�97 ���������������=�1���>������1����������/�1�$�����1������������������������# �?�*./�-������0��1��������������,����������"��������4����"���?�#/'"-��..'"/@"A?A2/B����������������"���-�@-��'�# �?�*./7 ����������������������?�$�������?���0�&�����������������)���������������������C������49 ��#�?�*./�(����97 ������������E����&4/C���������7)E���������������)���������������������C������49 ��#�?�#/��&��'������97 ������������E����&4/C���������7)E���������������?�$��������������� ��������(�1�������������������C�����49-�/�?/�?�#/��&��'�������A"�2�����4M7���

ORACLE

Page 189: Java in Datenbanksystemen

������� ����� ���������������������������������� ��

�������������-%��4YJ797 �����������������C�����49-�/�?/�?�*./�(�����4�����-%��4YJ7B�������������������&��'�������797 �����������������C�����49A@"/�?�A@?��(�����2�.�/"�4Q*+OQB��������������&��'������4Q+���&��QBQA�1�����QBQZ$����Q7�797 �����������������C�����49A@"/�?�A@?��(�����2�.�/"�4Q����QB��������������&��'������4Q"����1���QBQ ��1�(��1QBQA�����Q7�797 �����������������C�����49A@"/�?�A@?��(�����2�.�/"�4Q+���$�&�QB��������������&��'������4Q?�G��QBQ.�����QBQ%��$��1Q7797 ���������������F�������(�&�����������������,������C�����F����49"/./-?�(�����B(���������+�(�����������������(97 ��������������������+��1�����!����������������C�47 ������������������-./�������/�=�������1��!������������������-./�������?���&���������������������������,�44���������"��7�7�1�������49����97 ������������"����������������49�������������?���9�N�������������������1��"F.?���@���477 ������������"����������������49������&�������.T�1��9�N���������������������1�&477 �������������������H *-���������:������G����������������������������������(�&���1��$���H *-�������?��!����������������������������������,���1�������49����97 ������������"����������������49������������&�������*�����������������������9�N�������1��*��?���@���477 ������������"����������������49������������&�������*������9�N�������������������1��*��?���47N�9<�97 ������������"����1�(���� ���������������������������$������ ��������������)���������������������%�����(�����������=����1����������������������(�����,���1���$����49����97���"����147 ������������������"���������������49<�.���2������(���������������������������9N(����7 �����������������������"U�*/!��������������������������������������������������/����������?�$��������B�"������������������������������&���������������������������,�44���������"��7�7�1�������49����97 ���������������������H�2���������������"F.�������������!���������������������$=�&������$�����:����G1�1�$���=���B�������&����������������������������G1�$��������������H����������?�����������������������$����56������,�4�$����567�������1�������47 ��������������������� ������:�����A�&���B������������B���1�$��������������������(���4�����,J ��V�������1�& ��NN7��������������������"���������������49���������C�9N�N9�,���������������������9N����5�67 ���������������������>@ /��@U!��������������������������������������������������*�:���&��������������������������������� �������������������,������������������������ ��������������� ��������49-%��'2�����9B����7

Page 190: Java in Datenbanksystemen

� ! ������������ ����� �����������������������

���������������������A���C�J����T�����!����������������������5J6�,�9@�=����G9 ������������������������-./���������������������������������������'������,���=������4���������B����B�����������������������7 ����������������44���������"��7�7������������49����9B��'�����7 ���������������������=�������+01��&G����������"U�*/���������!�������������������������&����=����������"��������H *-I�J����G������������������������������=���������������������������G���������� ������������ ����$��G����!����������������������(��&��=47 ������������������"���������������49.���1�T�������2������(���������������������������9N(����7 ��������������������$�������,���1�������49����97 �������������������������%�(�����������"������2��������1�$������������������������"�������,���$�������1������"��47 ������������������=&���4������C�477��������������������������� ��������"��������&T������A���CB�������������������������������:=���������O���������������������������"���������������49���������C�9�N�����������������������������1���$����4D7N9�,�9�N�����1���$����4I77 ������������E=&���4����C�477 ���������������$�&���$������������������������������������������������47 �������������������47 ��������E������������(�&���&��H *-���&��$�&�����1!������������������������"F.�+��&�����=��(�������������"F./C�������������������&4"F./C���������7��������)������������ *����&�="F./C�������4�7 ��������E������������&4/C���������7)������������"���������������49<�������&������1�����������<�97 �������������������"���G?����47 ��������E����E��/��������+���E

Der Ausschnitt der Ausgabe des Beispiels 5.2 sieht folgendermaßen aus:

2��$�����1�:�� *��;�������������?���"-�??�-%��'2�����������&�������.T�1��Y������������&�������*�����������-%��������������&�������*������D.���2������(���������*+O���������C�J�,�+���&�����������C�D�,�A�1��������������C�I�,�Z$����D����&�4�7��G��������

Page 191: Java in Datenbanksystemen

������� ����� ���������������������������������� � �

.���1�T�������2������(���������*+O���������C�D�,�@�=����G���������C�I�,�A�1��������������C�Y�,�Z$����

Am Anfang des Beispiels 5.2 werden (genauso wie in Beispiel 5.1) die spezifischenOracle-Pakete für JDBC (oracle.sql und oracle.jdbc.driver) importiert.

Im main-Programm wird zuerst der zu erstellende Typ (char_varray) und die zuerstellende Tabelle (firma) mit der DROP TYPE- bzw. DROP TABLE-Anweisunggelöscht. Falls eines dieser Objekte nicht existiert, wird eine Instanz der Klasse Excep-tion ohne eine Maßnahme durchzuführen aufgerufen (d.h. der Funktionsrumpf derAusnahme in dem catch-Teil ist leer).

Danach wird der Objekttyp char_varray als Vektor mit 6 alphanumerischen Elementen(der Länge 30) mit Hilfe der CREATE TYPE-Anweisung erstellt. Mit Hilfe dieses Vek-tors wird in der Tabelle firma die Spalte orte definiert. (Die zweite Spalte der Tabelle isteine alphanumerische Spalte.)

Mit Hilfe der INSERT-Anweisung werden anschließend drei Reihen der Tabelle firmaeingefügt. Beim Einfügen der Werte für die Vektor-Spalte orte wird der Konstruktorchar_varray (so wie wir das schon in Kapitel 2 erörtert haben) verwendet. Die anschlie-ßende Abfrage, die alle drei Reihen liest, wird mit Hilfe der executeQuery()-Methodeausgeführt. (Die dazugehörende SELECT-Anweisung hat eine allgemein bekannteForm.)

Der anschließende Teil des JDBC-Programms, in dem die Vektor-Elemente ausgelesenwerden, ist in zwei Abschnitte unterteilt. Im ersten werden die Vektor-Elemente mitHilfe der spezifischen Oracle-Erweiterungen ausgelesen, während im zweiten Teil dieallgemein zur Verfügung stehenden JDBC-Mittel für dieselbe Aufgabe verwendet wer-den.

Im ersten Teil wird eine Instanz (array) der Oracle-spezifischen Klasse namens ARRAYdefiniert. Danach wird mit Hilfe der getARRAY-Methode die Verbindung zwischendieser Instanz und der Vektor-Spalte orte hergestellt und die Ergebnismenge für diesenVektor ermittelt. (Die getARRAY()-Methode ist eine Erweiterung der JDBC-MethodegetArray().) Die ResultSet-Instanz rs wird dementsprechend in eine Oracle-spezifischeErgebnismenge mit Hilfe der OracleResultSet-Klasse umgewandelt.

Nachdem die Instanz array initialisert wurde, ist es möglich, einige Oracle-spezifischeMethoden anzuwenden. Dementsprechend wird mit Hilfe der getSQLTypeName()-Methode der Datentyp der Elemente der Vektor-Spalte orte ermittelt. Eine weitereMethode – length() – gibt die Kardinalität des Vektors aus, d.h. die Anzahl der Vektor-Elemente für die aktuelle Reihe.

Page 192: Java in Datenbanksystemen

� � ������������ ����� �����������������������

Im zweiten Teil werden die von JDBC allgemein unterstützten Methoden, die in Bezugzum Vektor stehen, dargestellt. Mit der Methode getBaseTypeName(), die zur Schnitt-stelle jdbc.sql.Array gehört, kann der SQL-Datentyp des referenzierten Elementesermittelt werden. (In diesem Fall handelt es sich um den alphanumerischen Datentyp,d.h. CHARACTER.) Die zweite Methode – getBaseType() – ist ähnlich der vorherigen,ermittelt aber den JDBC-Datentyp des referenzierten Elementes.

In dem AUSGABE-Teil des Beispiels werden für jeden Firmennamen (der der String-Variablen firma zugewiesen wird) die entsprechenden Vektor-Elemente ermittelt undausgegeben. Dies wird mit Hilfe der Instanz array durchgeführt. Diese Instanz wird inVerbindung mit der Vektor-Spalte orte gebracht, und anschließend werden einzelneElementewerte in den Vektor namens values gespeichert und mit Hilfe einer for-Schleife ausgegeben.

Im Programmteil namens ÄNDERUNG wird mit Hilfe einer UPDATE-Anweisung dieÄnderung eines Vektor-Elementes in jeder Reihe der Tabelle firma durchgeführt. Weildie Änderung nicht direkt ausgeführt werden kann, wird im Programm eine Instanz(descriptor) der Klasse ArrayDescriptor erstellt.

In der Programmreihe

��������'������,���=������4���������B����B�����7

wird die erstellte Instanz descriptor verwendet, um eine neue Oracle-spezifischeInstanz (val_array) zu initialisieren. Die vorher veränderten Vektor-Werte befindensich in der Instanz namens values. Im Beispiel wird eine Instanz der Klasse Prepared-Statement verwendet, um die Änderungen der Daten durchzuführen. Dazu wird dieseInstanz in eine Instanz der Klasse OraclePreparedStatement umgewandelt, um dieOracle-spezifische Methode setARRAY() aufrufen zu können. (Alternativ könnte manhier auch die Methode setREF() der OracleResultSet-Klasse verwenden.)

�������

Wie aus der obigen Erörterung ersichtlich, bieten die Oracle-spezifischen Methodenin Bezug auf den ARRAY-Datentyp erweiterte Funktionalität im Vergleich zu denallgemein von JDBC unterstützten Methoden.

�������

Bevor eine Instanz vom Typ Array erstellt werden kann, muss eine Instanz derArrayDescriptor-Klasse für den gegebenen SQL-Datentyp existieren. Falls einesolche Instanz nicht existiert, muss der Programmierer diese erstellen, indem derSQL-Datentyp der Kollektion (im Beispiel CHAR_VARRAY) und die Instanz derConnection-Klasse (con) an den Konstruktor übergeben werden. (Die Connection-Instanz wird benutzt, um die Metadaten zu holen.)

Page 193: Java in Datenbanksystemen

������� ����� ���������������������������������� � �

Im letzten Programmteil werden die aktualisierten Daten noch einmal gelesen: Zuerstwird mit Hilfe der refreshRow()-Methode die aktuelle Reihe aktualisiert und dann mitHilfe der getResultSet()-Methode der Schnittstelle java.sql.Array die Ergebnismengeerstellt, die alle Elemente des Vektors enthält. Diese Ausgabe ist äquivalent zur vorhe-rigen, jedoch werden ausschließlich JDBC-Funktionen und keine Oracle-spezifischenErweiterungen verwendet.

����$ % &�'��'� �� �(�� �� �

Die Erstellung und Bearbeitung der geschachtelten Tabellen innerhalb eines JDBC-Pro-gramms wird mit dem folgenden Beispiel veranschaulicht.

Beispiel 5.3

������������ ��������������� ���������������� ���������������������������� ��������!���������������� ����������������"������������#�������"��������!���������������$���������� ����������������� ������'@����)����������(�������� *+"�,� *�������-./ ������$��0��1���2����$���(��� *�3�1��((�������������-��������������,��� ����������"�������������,��� ��������������"�����,��� �������������������������������������������������$������������������4"����1���1�567����)���������(4�8 *�������� ���$�� �����4 *+"77������� ���������(4�4����,� *����������� ���*��4 *+"77�,,���7������� �������������������)������������"���������������492��$�����1�:�� *��;<�97 ���������������=�1���>������1����������/�1�$�����1������������������������# �?�*./�-������0��1���������������,����������"��������4����"���?�#/'"-��..'"/@"A?A2/�������������B����"���-�@-��'�# �?�*./7 ����������������������?�$�������?���0�&�����������������)���������������������C������49 ��#�?�*./���$�����97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E�����������������)���������������������C������49 ��#�?�#/����=�����'�97

ORACLE

Page 194: Java in Datenbanksystemen

� � ������������ ����� �����������������������

������������E����&4"F./C���������7) *����&�="F./C�������4�7 E����������������)���������������������C������49 ��#�?�#/������'�97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#�?�#/�����'�97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������?�$��������?����������������������������C�����49-�/�?/�?�#/�����'���"��*H/-?�4���&�����������������2��-%��4YJ7B���������2��-%��4IJ7797 �����������������C�����49-�/�?/�?�#/������'���"��*H/-?�4�����'���������������A@?B����������'�B�����'�'��&���A@?797 �����������������C�����49-�/�?/�?�#/����=�����'���"�?�*./���������������������'�97 �����������������C�����49-�/�?/�?�*./���$������4��$'���A@?B����������������������������'�B����=���������=�����'�B�������������#�A+����;/�4��$'��77�@/"?/ �?�*./����=������������������"?��/��"����'��$��97 ��������������� ��������(�1��������������"���������������4�����C�����������49A@"/�?�A@?����������������$������2�.�/"�4DIYKLB������'�4DIYB�����'�4�������������Q+����QBQ%��Q7B�YK7B�����=�����'�4�����'�4DIKB�����������������'�4Q+����QBQ����:Q7B�DK7B������'�4DILB�����������������'�4Q+����QBQ-&������Q7B�IR77797�������������N9����&������1�(�1�97 ������������"���������������4�����C�����������49A@"/�?�A@?����������������$������2�.�/"�4IYKLDB������'�4IYDB�����������������'�4Q"�&������QBQU���1Q7B�KS7B����=�����'�4������������������'�4IYIB�����'�4Q"�&�����QBQ+�����Q7B�LM7B������������������'�4IYYB�����'�4Q*��&����QBQ%�$���Q7B�KI77797�������������N9����&������1�(�1�97 ������������"���������������4�����C�����������49A@"/�?�A@?����������������$������2�.�/"�4YKLDIB������'�4YDIB�����'�4Q%�$��QB�������������Q%�1�Q7B�MS7B�����=�����'�4�����'�4YDYB�����������������'�4Q"�&�&����QBQ/��GQ7B�IM7B������'�4YDKB�����������������'�4Q+��:1��QBQ �����Q7B�LX77797�������������N9����&������1�(�1�97 ������������"���������������4�����C�����������49A@"/�?�A@?��������������?�*./4"/./-?������=���������+���$��������O%/�/�����������������$'���,�QIYKLDQ7�2�.�/"�4�����'�4YDYB�����������������'�4Q"�&�&����QBQ/��GQ7B�IM7797�������������N9����&������1�(�1�<�97 ���������������F�������(�&�����������������,������C�����F����49"/./-?���$'��B���=���������+���������������$�����97 ����������������������� ������������������$���,�YKLDI ������������=&��4����C�477)�����������������������"U�*/!����������������������������������������������3��������@/"?/ �?�$������=���������������������������"���������������49.�����$������9�N

Page 195: Java in Datenbanksystemen

������� ����� ���������������������������������� � �

���������������������1��A��49��$'��97N9!97 ���������������������@/"?/ �?�*./���������������������������������������,�������������������44���������"��7�7�1�������49���=�����97 ���������������������@/"?/ �?�*./���1�$������������������������������4�����7 ���������������������>�����������@/"?/ �?�*./�/�����1�������������������������(��G����������������&����&��$���������������������������$����:����(���������$��G��������1�����?���������������������������������&�G���������������&���1��������# �?/������������������������=����1��������������=�����B�����������������������������������1�����&���?�$������G�������&��=��[�������������������(4��1��A��49��$'��97�,,���$��7)����������������������#�������"��������������,����������������������������������"��������49�# �?/�?�*./4"/./-?����=�������������������������������+���$������O%/�/���$'���,�Q9N���$���N9Q7�������������������������"/?����������������,�W�O%/�/��������'���,�YDK97 ����������������������44�����#�������"��������7����7���"����14DB�����������������������9 ��97 ����������������������������C�����47 ����������������������"���������������4�����1��������-����47N9��������������������������&�4�7��G��������97 ��������������������������G���������� ������������ ����$��G����������������������������!��������������������������(��&��=47 ����������������������"���������������49.�����$������9�N�������������������������1��A��49��$'��97N9�������!97 ����������������������������,�����������������������44���������"��7�7�1�������49���=�����97 ��������������������������������4�����7 �������������������E������������E���������������$�&���$��������������������������������������������������47 �������������������47 ��������E������������(�&���&��H *-���&��$�&�����1!��������������������������"F.�+��&�����=��(�������������"F./C�������������������&4"F./C���������7��������)������������ *����&�="F./C�������4�7 ��������E������������&4/C���������7)������������"���������������49<�������&������1�����������<�97 �������������������"���G?����47 ��������E����E��/��������+������������1�$�������������������������������������������4���������7)��������"��������������49������)�97 �����������)���H�2���������������"F.�������������!

Page 196: Java in Datenbanksystemen

� � ������������ ����� �����������������������

�������������$����56������,�4�$����567�����1�������47 ������������(���4�����,J ��V�������1�& ��NN7�)�����������������(4����5�6���������(��������������7�������������������������������������4�4�������������7��������������������������������5�67 �����������������(4����5�6���������(���������"?��-?7��������������������������������"?��-?4�4��������"?��-?7��������������������������������5�67 ������������������������������������������"��������������4�����5�6N9<�9�7 ������������E������������"���������������49<�E�97 ��������E����&4"F./C���������7)������������ *����&�="F./C�������4�7 ��������E����E���������1�$��������������"?��-?��������������������"?��-?4"?��-?������7)��������"��������������49<�<�"?��-?�)�97 �����������)�������������$����������$���56�,�������1�������$���47 ������������(���4�����,J ��V�����$������1�& ��NN7�)���������������(4�����$���5�6���������(��������������7������������������������������������4�4�������������7��������������������������������$���5�67 ������������������(4�����$���5�6���������(���������"?��-?7�������������������������������"?��-?4�4��������"?��-?7��������������������������������$���5�67 ������������������������������������"��������������4�����$���5�6N9<�97 ������������E������������"��������������49�E�97 ��������E����&4"F./C���������7)������������ *����&�="F./C�������4�7 ��������E����EE

Der Teil der Ausgabe des Beispiels 5.3 sieht folgendermaßen aus:

2��$�����1�:�� *��;D����&������1�(�1�D����&������1�(�1�D����&������1�(�1�D����&������1�(�1�.�����$������DIYKL!������)��������"?��-?�)�DIK��������"?��-?�)�+����������������:����E�DK����E��������"?��-?�)�DIL��������"?��-?�)�+������������-&��������������E�IR����E

Page 197: Java in Datenbanksystemen

������� ����� ���������������������������������� � �

E.�����$������YKLDI!������)��������"?��-?�)�YDY��������"?��-?�)�"�&�&����������/��G�����E�IM����E��������"?��-?�)�YDK��������"?��-?�)�+��:1���������� �������E�LX����EED����&�4�7��G��������.�����$������YKLDI�������!������)��������"?��-?�)�YDY��������"?��-?�)�"�&�&����������/��G�����E�IM����E��������"?��-?�)�YDK��������"?��-?�)�+��:1���������� ��������E�LX����EE

Beispiel 5.3 beinhaltet JDBC-Anweisungen bezüglich der geschachtelten Tabellen.Genauso sind die in diesem Beispiel verwendeten JDBC-Klassen und Methoden ähn-lich den schon verwendeten Klassen und Methoden in den vorherigen beiden Beispie-len. Aus diesem Grund werden wir abgesehen von der Beschreibung der MethodenprocessARRAY() und processSTRUCT() auf die Beschreibung weiterer Teile des Bei-spiels verzichten.

Die Methode processARRAY() ist eine benutzerdefinierte Methode, die für die Ausgabeeines Oracle-Vektors in Beispiel 5.3 verwendet wird. Diese Methode übernimmt einenOracle-spezifischen Vektor und speichert ihn in der ARRAY-Instanz arr. Mit Hilfe derMethode getArray() werden die einzelnen Vektor-Elemente in die Instanz namensvalues gespeichert. Diese Instanz ist vom Java-Typ Object, weil die Vektor-Elementejeden möglichen Datentyp (ARRAY, STRUCT usw.) haben können. Die beiden if-Anwei-sungen in der for-Schleife der Methode werden verwendet, um zu testen, ob Vektor-Ele-mente entweder Vektoren oder Oracle-Strukturen sind. Falls die Vektor-Elementewieder Vektoren sind, wird die Methode processARRAY() rekursiv aufgerufen. Falls dieVektor-Elemente Oracle-Strukturen sind, wird die zweite Methode processSTRUCT(),aufgerufen.

Die benutzerdefinierte Methode processSTRUCT() gibt eine Oracle-Struktur aus. Weildie Implementierung dieser Methode der Implementierung der vorher beschriebenenMethode processARRAY() weitestgehend entspricht, werden wir auf ihre Erläuterungverzichten.

Zur Änderung der Daten wird im Beispiel wieder eine Instanz der Klasse Prepared-Statement in Verbindung mit einer UPDATE-Anweisung verwendet. In Kombinationmit den vorherigen Beispielen könnte man hier jedoch eine allgemeinere Änderungs-routine implementieren, die die gelesenen Daten wieder mit Hilfe einer Typ-Abbil-dung in eine eigene Java-Instanz abbildet und so eine direkte Änderung der Datenermöglicht.

Page 198: Java in Datenbanksystemen

� � ������������ ����� �����������������������

��� ���������� ���� ��� �� ���� �� ���� ��� ��

)*���+),

Informix hat folgende Erweiterungen, die in Bezug zur Objektorientierung stehen:

� benutzerdefinierte Datentypen

� Reihentypen

� Kollektionen

� Typ- und Tabellenhierarchien.

Reihentyp und Kollektionen werden im nächsten Abschnitt behandelt, während Typ-und Tabellenhierarchien in einem separaten Abschnitt erläutert werden.

����� � ��� �' ��������-�� ���� ��� ��)�.�/�0

Das folgende Beispiel zeigt die Verwendung des Reihentyps und der KollektionenLIST (Liste) und SET (Menge).

Beispiel 5.4

������������ ��������������� ���������������� ����������������� ��$������A(C'-�������)����������(�������� *+"�,� *����A@���+A\ ������$��0��1���2����$���(��� *�3�1��((�������������-��������������,��� ����������"�������������,��� ��������������"�����,��� �������������������������������������������������$������������������4"����1���1�567����)���������(4�8 *�������� ���$�� �����4 *+"77������� ���������(4�4����,� *����������� ���*��4 *+"77�,,���7������� �������������������)������������"���������������492��$�����1�:�� *��;<�97 ������������������������� *�2������G0�����G��������������(�����������������������"�������&1�(�&���=���������������������,�����������"��������47 ����������������������?�$�������?���0�&�����������������)���������������������C������49 ��#�?�*./�$��&97

Informix

Page 199: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �

������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/�$��&'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/������'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������?�$��������?����������������������������C�����49-�/�?/���O�?�#/������'��4�����������������-%��4IJ7B���������"/?4-%��4IJ7�@�?�@�..7�797 ���������������P�����-�U��������������'�����:���/����������������������������'���$��G���(������?���������1������������"���������������49�����'�������97 �����������������C�����49-�/�?/���O�?�#/�$��&'��4�$��-%��4DY7�@�?�������������@�..B��������'����.A"?�4�����'��@�?�@�..7B�������������$��&'�����-%��4LJ7�797 ������������"���������������49$��&'�������97 �����������������C�����49-�/�?/�?�*./�$��&����?�#/�$��&'��4#�A+����������������;/��4�$�7797 ������������"���������������49$��&������97 ������������"����1�"F.�,�9A@"/�?�A@?��$��&�2�.�/"�4QY�RYILSS�YY�RQB�������������<9.A"?)��O4Q+�((��QB�"/?)Q"�����QE7B���������������������������O4Q?��������QB�"/?)Q�������(QE7B���������������������������O4Q3�����QB�"/?)Q-&������QE7��������������������������E<9BQ/�(�&���1�������H���Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ������������"F.�,�9A@"/�?�A@?��$��&�2�.�/"�4QD�LMLRI�JKL�XQB�<9.A"?)���������������������������O4Q"&����QB�"/?)QH�&�QE7B���������������������������O4Q%�QB�"/?)QO��QE7B���������������������������O4Q+�1��QB�"/?)Q ����QE7�E<9BQU���������������������������������O�����1� -/�����������Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ������������"F.�,�9A@"/�?�A@?��$��&�2�.�/"�4QJ�KXD�LRRDX�KQB�<9.A"?)���������������������������O4Q"���QB�"/?)Q*���QE7B���������������������������O4QU��G��QB�"/?)QU���&QE7B���������������������������O4Q"���&QB�"/?)Q#��QBQ?�$��QE7��������������������������E<9BQ����?�����$��������������+�����1Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ����������������$(��1�����������&���������������,������C�����F����49"/./-?��$�B��������'���B�������������$��&'��������+�$��&�O%/�/��$���G��QJ�]Q97 ������������"���������������49�$(��1����1�(�&��<�97 ���������������?���+���?�$���������B��������*����:����(�����������������������?�����(������;����$:�$�������������������������+�������,�����1��?���+��47 �������������������49�����'�9B�-��(��@���49�����'�977 ������������������?���+��4���7 ��������������� �(����?���������1�$���A�(����C

Page 200: Java in Datenbanksystemen

�!! ������������ ����� �����������������������

�����������������O�,��������"��������������������.A"?�,���������������.�����������������"/?�+�.?A"/?�,����������%�&"�������������������������������� ������������"����1��$� ����������������"����I ������������=&��4����C�477)�������������������"������$�����!�����������������$��,���1���$����49�$�97���"����147 ������������������������.�����������"���������������������������.��������'����,�4�����.��7�������������������1���$����49�������'���97 ���������������������������������B�������$������������&�������������������������������'������&����?��������1��������������������&���?��������1�=�������������&�����$��G�������������������������?���"���������&���������������������$����56���������,������'�����������47 �����������������������$�����������������������'����������=��������������������������-����1�(��G���������&�������&���������������������&���?���������1�����������&��������"�����56����������������������������������������:�(��&���=��������������������������'�56����,���=������'�5����������1�&6 ����������������(��4�����,J ��V����������1�& ��NN7)�����������������������3�=����1�����O�����������������'�����������������������������5�6�,�4�����'�7��������5�6 �������������������������1�$��������������B�����&��������?���������������������������(����������"����1�+��&�����������������������"���������������4��5�67 ����������������E�������������������>�����������O�����4����D��������=����1�T�����7������������������5J6������,�9"�&����9 ������������������� �����������I�2��������$�G�����!�����������������$����56���=���,���=��$����5I6 ������������������=��5J6�,�9����9 ������������������������2������������&���������������+��&������������������������������'�����������������������=��5D6�,���5J6�1��2������4J7 �������������������2������������&���������������+��&������������'����������������������$��G������:��������������������5J6���2�������4��=��7 ������������������������������������������1�T�������������'���������������������G������������������������������'������4JB��5J67 �������������������>������1��������������������� *��$�������������������������#�������"������������������������#�������"��������������,����������������������������"��������49�# �?/�$��&�"/?��������'����,�W�����������������O%/�/��$���G��Q9N�$�N9Q97 ������������������������$����4DB�����'���7 ����������������"���������������4������C�����������47N9����&�4�7������������������G��������97

Page 201: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �!�

�����������������������������1�$������1�T��������O����B�=����$�������������������I�,������C�����F����49"/./-?��$�B��������'���B�����������������$��&'��������+�$��&�O%/�/��$���G��Q9N�$�N9Q97 �����������������I���C�47 ����������������������,��I�1�������49�������'���97 ������������������������,�4�$����567�������1�������47 ����������������(��4�����,J ��V����������1�& ��NN7)��������������������"���������������44�����'�7�������5�67 ����������������E������������E���������������$�&���$���������������������������������������������������47 �������������������47 ��������E������������(�&���&��H *-���&��$�&�����1!��������������������������"F.�+��&�����=��(�������������"F./C�������������������&4"F./C���������7��������)������������ *����&�="F./C�������4�7 ��������E������������&4/C���������7)������������"���������������49<�������&������1�����������<�97 �������������������"���G?����47 ��������E����E��/��������+���E

Die Ausgabe des Beispiels 5.4 ist:

2��$�����1�:�� *��;�����'�������$��&'�������$��&������D����&�����1�(�1�D����&�����1�(�1�D����&�����1�(�1��$(��1����1�(�&��@���!�"�������������������2�������!�*�������������������B@���!�U��G��������������2�������!�U���&���������������B@���!�"���&����������������2�������!�#���������B�?�$�������������B1�������4+������7D����&�4�7��G��������@���!�"�&������������������2�������!������������B�*����������������B@���!�U��G��������������2�������!�U���&���������������B@���!�"���&����������������2�������!�#���������B�?�$�����������B

In Beispiel 5.4 wird zuerst die Verbindung zur Datenbank hergestellt. Das danacherstellte Statement-Objekt ist nicht änderbar (updatable), da die verwendete Informix-Version dies (noch) nicht unterstützt. Aus diesem Grund wird die Änderung in diesemBeispiel auch nicht über die ResultSet.updateObject(), sondern mit Hilfe einer Pre-paredStatement-Instanz durchgeführt.

Page 202: Java in Datenbanksystemen

�!� ������������ ����� �����������������������

In den folgenden try-catch-Blöcken werden die Tabelle und die dafür benötigten Rei-hentypen aus der Datenbank gelöscht. Dabei muss beachtet werden, dass die Typenvon dem speziellsten bis hin zum allgemeinsten gelöscht werden, um keine Fehlermel-dungen des Datenbanksystems zu verursachen. Da eine DROP TYPE- bzw. DROPTABLE-Anweisung auf einen vorhandenen Typen oder eine vorhandene Tabelle einenvon der Datenbank abhängigen Fehler-Code liefert, kann man hier die aufgetretenenFehler individuell innerhalb des catch-Abschnitts verarbeiten.

Danach werden die im Beispiel benötigten Reihentypen und die entsprechenden Tabel-len erzeugt. Dies erfolgt mit der in Kapitel 2 erläuterten CREATE ROW TYPE-Anwei-sung. Die im folgenden eingefügten Werte werden dann abgefragt und die Ergebnissein einer ResultSet-Instanz abgelegt.

Um einen Informix-Reihentyp mit Hilfe eines JDBC-Programms zu lesen und anschlie-ßend zu ändern muss ein äquivalentes Java-Objekt erzeugt werden. Dazu kann beiInformix das im Archiv namens ifxtools.jar enthaltene Programm ClassGenerator ver-wendet werden. Sobald dieses Archiv im CLASSPATH eingetragen ist, kann mit Hilfevon ClassGenerator aus dem Reihentyp autor_t die Java-Klasse autor_t.java erstelltwerden. Damit der Reihentyp korrekt aus dem ResultSet gelesen werden kann, mussdem Connection-Objekt die Typabbildung mitgeteilt werden. Dies erfolgt über dieInstantiierung einer Abbildung, in der das Wertepaar <Reihentyp>, <Javatyp> einge-tragen wird. Diese Abbildung wird dann dem Connection-Objekt übergeben. Folgen-der Ausschnitt erfüllt diese Aufgabe:

���������������������+�������,�����1��?���+��47 �������������������49�����'�9B�-��(��@���49�����'�977 ������������������?���+��4���7

Zu beachten ist hierbei, dass jeder Kollektionsdatentyp bei Informix einem bestimmtenJava-Datentyp entspricht. Standardmäßig werden ROW in java.sql.Struct, LIST injava.util.ArrayList und SET bzw. MULTISET in java.util.HashSet konvertiert.

Die mit Hilfe des ClassGenerator aus dem Reihentyp autor_t erstellte Dateiautor_t.java (mit der Java-Klasse autor_t) sieht folgendermaßen aus:

��������������� ���������������&�� ��$�����������'�����������"F. ���)������$���"����1����� ������$����������������� ������������"����1��'���� ������$���"����1�1��"F.?���@���47�)��������9�����'�9 �E������$������������"F.�4"F.A����������B�"����1�����7��&��="F./C�����������)���������'�����,�����

Page 203: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �!�

�������������,�����������"����147 �����������������,����������������47 ����E������$��������=����"F.�4"F.������������7��&��=�"F./C�����������)��������������=����"����14����7 ��������������=���������4��������7 ����E�������:�T�:��&������������������G�������(������*�����!�������������$���������2��������:����G1�$��������$����$�����1��2������4�����7)�����������)�������������������44�$����567���������1�������4775�6 ��������E����&4/C���������7)E

����������������� ����E���������:�&�����2��������:����G1�$��������$�������1��2�������47)�����������)�������������������44�$����567���������1�������477���1�& ��������E����&4/C���������7)E���������������J ����E������$����������2�������4�$����56�����7)�����������)������������������������,���=����������������U�����������4���������1��*��?���@���47B�����B�������������������������1��*��?���477 ��������E����&4/C���������7)E����E���������1�$�����A�&��!������$���"����1���"����147����)��������"����1��,�9@���!�9N����N9�2�������!�9 �����������)���������$����56���,�4�$����567����������1�������47 ��������(��4�����,J ��V����1�& ��NN7�������������N,��5�6N9B�9 ��������E����&4/C���������7)E��������������� ����EE

�������

Der Großteil dieser Datei wird vom ClassGenerator erzeugt. Die hinzugefügtenMethoden getVorname(), getVornamen(), setVornamen() und toString() sind nurzur Vereinfachung und besseren Verständlichkeit da, und deswegen nicht unbe-dingt notwendig.

Page 204: Java in Datenbanksystemen

�!� ������������ ����� �����������������������

Die Klasse dient als Behälter der Daten aus dem Typ autor_t. Dieser wurde im Haupt-programm folgendermaßen erstellt:

-�/�?/���O�?�#/������'�4�����-%��4IJ7B���������"/?4-%��4IJ7�@�?�@�..77

Die Methoden getSQLTypeName(), readSQL() und writeSQL() werden automatischimplementiert (sie implementieren die SQLData-Schnittstelle) und sorgen für die kor-rekte Übernahme der Daten aus der Datenbank in das Java-Objekt. Der Reihentypautor_t enthält den Namen des Autors sowie eine zweite Spalte – vornamen –, die alsMenge definiert ist. Der ClassGenerator bildet den Namen in einen Java-String unddie entsprechenden Vornamen in eine Instanz der Klasse java.sql.Array ab. Die Metho-den getVorname(), getVornamen() und setVornamen() wurden hinzugefügt, um aufdie Daten in diesem Vektor zugreifen zu können und sie anschließend zu verändern.

getVorname() liefert einen Vornamen mit dem übergebenen Index zurück. Die Anzahlverfügbarer Indizes (d.h. die Anzahl der Vektor-Elemente) gibt die Methode getVorna-men() zurück. In beiden Methoden wird der Vektor, der als Elemente Vornamen einesAutors hat, mit Hilfe der in der Array-Schnittstelle vorhandenen Methode getArray()in ein Object[] konvertiert, und dann auf diesen zugegriffen.

Da Informix im Gegensatz zu Oracle keine eigene Implementierung der Array-Schnitt-stelle enthält, können Werte hier nur über die wenigen von JDBC verfügbaren Metho-den gelesen werden. Eine Änderung der Kollektionstypen ist gar nicht vorgesehen.Um einen Kollektionstyp (wie z.B. eine Instanz von java.sql.Array) verändern zu kön-nen, ist es notwendig, eine eigene Implementierung dieser Schnittstelle vorzunehmen.Dazu wurde die Datei GenericArray.java mit der gleichnamigen Klasse erstellt, wel-che rudimentär die Klasse java.sql.Array implementiert. Jede Methode dieser Klassegibt aus, wann sie aufgerufen wird, um genaueren Einblick zu erhalten, wann welcheArray-Methode von Java aufgerufen wird. Da die Klasse nur die für das Beispiel benö-tigten Methoden implementiert und diese nur aus return-Anweisungen bestehen, sollhier nicht weiter darauf eingegangen werden.

In der Methode setVornamen() wird der Vektor, der als Elemente Vornamen einesAutors hat, durch einen neuen ersetzt. Dazu wird ein neues Objekt GenericArray mitdem übergebenen Objekt-Array erstellt. Die toString()-Methode schließlich dient einerübersichtlichen Ausgabe aller Daten des Objektes. Dazu werden der Name sowie alleElemente des Vektors mit den Vornamen ausgegeben.

Nach der Rückkehr in das Hauptprogramm werden alle Einträge der Ergebnismengebearbeitet. Dabei wird der Wert der Spalte isbn als Identifikator geholt, um spätereÄnderungen mit Hilfe von PreparedStatement durchführen zu können, weil einÄnderungs-Cursor (noch) nicht unterstützt wird. Mittels

�����.��������'����,�4�����.��7���1���$����49�������'���97

Page 205: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �!�

wird eine Instanz (autor_liste) der Klasse ArrayList geholt, weil eine Liste (wieautoren_liste) bei Informix standardmäßig in eine Instanz der Klasse ArrayList kon-vertiert wird. Die Instanz autor_liste enthält alle Autoren des gerade verarbeitetenBuches, die enthaltenen Elemente entsprechen also autor_t. Da wir die Abbildung desAutor-Typen zu Beginn verändert haben, wird jetzt ein Vektor erstellt, welcher alle Ele-mente der autor_liste enthält und entsprechend konvertiert werden muss. In der dazunötigen Schleife wird auch gleichzeitig die Information bezüglich der Autoren mit dertoString()-Methode ausgegeben.

Im folgenden Programmabschnitt kann man über die in autor_t definierten Methodendie Daten eines jeden Autoren lesen und schreiben. Zur Änderung des Vornamenswerden alle Vornamen des Autoren gelesen und anschließend einer davon geändert.Danach wird der Object-Vektor wieder mit Hilfe der Methode setVornamen() zurück-geschrieben. Die geänderten Daten eines Autors werden in die autor_liste mit derset()-Methode der Klasse ArrayList überschrieben.

Mit Hilfe einer Instanz der Klasse PreparedStatement werden die geänderten Datenin die Datenbank gespeichert. (Der vorher gelesene isbn-Wert hilft den richtigenDatensatz auszuwählen.)

Mit folgenden beiden Anweisungen

��������$����4DB�����'���7������C�����������47

kann dann die autor_liste zurückgeschrieben werden.

Mit Hilfe einer zweiten ResultSet-Instanz wird der gerade veränderte Datensatz nocheinmal abgefragt und ausgegeben (um die Änderung visuell zu bestätigen).

����� )�.�/�0#(��'� ����'� �

Die Erstellung und Bearbeitung der hierarchischen Tabellen sowie die Ausgabe undÄnderung eines STRUCT-Typs innerhalb eines JDBC-Programms wird mit dem fol-genden Beispiel veranschaulicht.

Beispiel 5.5

������������ ��������������� ���������������� ����������������� ���A(C'���&)����������(�������� *+"�,� *����A@���+A\

Informix

Page 206: Java in Datenbanksystemen

�!� ������������ ����� �����������������������

������$��0��1���2����$���(��� *�3�1��((�������������-��������������,��� ����������"�������������,��� ��������������"�����,��� �������������������������������������������������$������������������4"����1���1�567����)���������(4�8 *�������� ���$�� �����4 *+"77������� ���������(4�4����,� *����������� ���*��4 *+"77�,,���7������� �������������������)������������"���������������492��$�����1�:�� *��;<�97 ����������������,�����������"��������47 ����������������������?�$�������?���0�&�����������������)���������������������C������49 ��#�?�*./������&���97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/�G��'����'�������������������/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/�(����'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/������'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/������'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������)���������������������C������49 ��#���O�?�#/�����'���/"?�A-?97 ������������E����&4"F./C���������7) *����&�="F./C�������4�7 E���������������?�$��������?����������������������������C�����49-�/�?/���O�?�#/�����'�4���&�����-%��4IJ7�������������@�?�@�..B���������-%��4IJ7797 �����������������C�����49-�/�?/���O�?�#/������'��4�����-%��4IL7�������������@�?�@�..B�����-%��4IJ7�@�?�@�..B&�����������������A@?/U/��@�?�@�..797 �����������������C�����49-�/�?/���O�?�#/������'��4�'������B����������������������'�B������������'�B����(��'���A@?/U/�797 �����������������C�����49-�/�?/���O�?�#/�(����'��4(�����'���A@?/U/��������������@�?�@�..B�(�����'�����-%��4IL7�@�?�@�..B������������������������'�797 �����������������C�����49-�/�?/���O�?�#/�G��'����'��4(�����������������(����'�B(��G�����-%��4IJ77��@ /�������'�97 ������������"���������������49?����������97 �����������������C�����49-�/�?/�?�*./������&�������?�#/�������������G��'����'��4#�A+����;/��4�'��7797 ������������"���������������49?�$��������97 ������������"����1�"F.�,�9A@"/�?�A@?�������&����4�'��B�����B

Page 207: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �!�

�����������������B����(��'��B�(����B�(��G����7�2�.�/"�4������������SLRB���O4�Q+����QB�Q%��Q7!!����'�B��������������O4Q"����$��1QB�Q���=�1QB�X7!!�����'��B9N��������������������9JSRMLXKSB������O4DIB�Q*+OQB���O4Q+���&��QB������������Q%�������[�QB�DM7!!�����'�7!!(����'��B�Q+����$�����Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ������������"F.�,�9A@"/�?�A@?�������&����4�'��B�����B������B����������������(��'��B�(����B�(��G����7�2�.�/"�4SMJB���O4�QU��$��QB�������������Q#����Q7!!����'�B���O4Q������1QB�Q*��&�����[�QB�Y7!!������������������'��BJDMJXYXMSLYB��O4YKB�Q����QB���O4QA�1�����QB�������������QA����������[�QB�LM7!!�����'�7!!(����'��B�������������Q/��=��G��Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ������������"F.�,�9A@"/�?�A@?�������&����4�'��B�����B������B����������������(��'��B�(����B�(��G����7�2�.�/"�4SMDB���O4�Q"�&����QB�������������Q��������&Q7!!����'�B���O4Q"����1���QB�Q*�&�&�(���[�QB�������������DY7!!�����'��B9N��������������������9JDXDXKXMKSIB������O4IYB�Q���QB���������������O4Q���&���QB�Q.��������[�QB�S7!!������������������'�7!!(����'��B�QA�1������Q79 ������������"���������������4�����C�����������4"F.7�N�9����&�����������������1�(�1�97 ����������������$(��1���������������,������C�����F����49"/./-?�(��������+������&���97 ������������"���������������49�$(��1����1�(�&��<�97 ���������������?���+���?�$���������B��������*����:����(�����������������������?�����(������;����$:�$�������������������������+�������,�����1��?���+��47 ���������������(����'�����������������������"F. ����A����(�������������������������&T��(�������(�����?�����:�(��&����������������+��&����B����������1�$���=�������>������1����������������������&������� �����:��������(��&���������������������49(����'�9B�-��(��@���49(����'�977 ������������������?���+��4���7 ��������������� �(����?���������1�$���A�(����C�����������������O�,��������"��������������������.A"?�,���������������.�����������������"/?�+�.?A"/?�,����������%�&"������������������"����I ������������(����'��(����� ������������=&��4����C�477)������������������������������������H�����$��G��G���������������������������(�����,�4(����'�7��1���$����49(����97 ��������������������������������1�$��!�(����'����"����147�+��&�������������������"���������������49<�9N(����7 ����������������"���������������49<�>������"��������@�=����G97 ������������������������'��"�����������&�$��������$���+��&�����"����47�T���������������������(�������"����49@�=����G97

Page 208: Java in Datenbanksystemen

�!� ������������ ����� �����������������������

�������������������>������1��������������������� *��$�������������������������#�������"������������������������#�������"��������������,����������������������������"��������49�# �?/������&����"/?�(�����,�W�����������������O%/�/�(�����(�����'���,�9N(�����(����'��7 ������������������������$����4DB(����7 ����������������"���������������4������C�����������47N9����&�4�7������������������G��������97 ������������E���������������������&������&����������>������1�:��$��T��1��!������������"���������������49<���(��&���� ����$��G!97 �������������I�,������C�����F����49"/./-?�(��������+������&���97 ������������=&��4����C�477)����������������"���������������44(����'�7��1���$����49(����977 ������������E���������������$�&���$���������������������������������������������������47 �������������������47 ��������E������������(�&���&��H *-���&��$�&�����1���������������������������"F.�+��&�����=��(�������������"F./C�������������������&4"F./C���������7��������)������������ *����&�="F./C�������4�7 ��������E������������&4/C���������7)������������"���������������49<�������&������1�����������<�97 �������������������"���G?����47 ��������E����E��/��������+���E

Die Ausgabe des Beispiels 5.5 sieht folgendermaßen aus:

2��$�����1�:�� *��;?����������?�$���������$(��1����1�(�&���������^!�DI�����������!�*+O�������'��)�+���&��������������������B�%�������[����������B�DMB�E>������"��������@�=����G�������^!�YK�����������!�����������'��)�A�1��������������������B�A����������[������B�LMB�E>������"��������@�=����G�������^!�IY�����������!����������'��)����&�����������������B�.��������[���������B�SB�E>������"��������@�=����G��(��&���� ����$��G!�������^!�DI�����������!�*+O�������'��)�@�=����G�����������������B�%�������[����������B�DMB�E�������^!�YK�����������!������

Page 209: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' �!

�����'��)�@�=����G�����������������B�A����������[������B�LMB�E�������^!�IY�����������!����������'��)�@�=����G�����������������B�.��������[���������B�SB�E

Genauso wie im vorherigen Beispiel wird in Beispiel 5.5 auf eine PreparedStatement-Instanz zur Änderung der Daten zurückgegriffen. Beim allerersten Aufruf werden ent-sprechende Ausnahmen ausgegeben, falls die Typen noch nicht vorhanden sind.

Mit der execute()-Methode und der CREATE ROW TYPE-Anweisung werden mehrereReihentypen erstellt, welche hierarchisch organisiert sind. Mittels der execute-Update()-Methode und der INSERT-Anweisung werden drei Reihen in die Tabelle teil-nehmer eingefügt. Eine ResultSet-Instanz enthält alle mit der SELECT-Anweisunggelesenen Reihen, welche dem Typ firma_t entsprechen. Da es sich hierbei wieder umeinen Kollektionstyp handelt, benötigen wir wieder eine Typabbildung auf ein Java-Objekt, um die enthaltenen Daten zu lesen und zu verändern.

Die Datei mit der Java-Klasse firma_t heißt firma_t.java. Diese Klasse wurde von unsimplementiert, weil ClassGenerator den enthaltenen Struct-Typ nicht bearbeitenkann. Für eine Typabbildung wird aber lediglich eine Klasse benötigt, welche die SQL-Data-Schnitstelle implementiert. Im folgenden das Programm firma_t.java:

��������������� ���������������&�� ��$������(����'�����������"F. ���)������$�������(����'�� ������$���"����1����� ������������"�����������'����� ������������U������"����������� ������������"����1��'���� ������$���"����1�1��"F.?���@���47�)��������9(����'�9 �E������$������������"F.�4"F.A����������B�"����1�����7��&��="F./C�����������)���������'�����,����� ��������(����'���,�����������A��47 �������������,�����������"����147 �������������'������,�4"�����7������������$����47 ��������������,���=�U������"�����4�����'������1��"F.?���@���47B�����'������1�������$���477 ����E������$��������=����"F.�4"F.������������7��&��=�"F./C�����������)��������������=����A��4(����'��7 ��������������=����"����14����7 ��������������=����"�����4�����7 ����E�������:�T�:��&������������������G�������(������*�����!���������1�$�������"������?��

Page 210: Java in Datenbanksystemen

��! ������������ ����� �����������������������

������$���"����1������"�����4"��������7)���������$����56���� ��������"����1�,99 �����������)�������������,�9<�9�N����1��"F.?���@���47�N�9�)�9 ����������������,����1�������$���47 ��������E����&4/C���������7)�������������������99 ��������E��������(���4�����,J ��V������1�& ��NN7)�������������(4���5�6���������(�"�����7�������������������)���������������������N,������"�����44"�����7���5�67 ����������������E����&4/C���������7)E����������������N,����5�6N9B�9 ��������E���������N,�9E9 ��������������� ����E����������1���+��&�����(������������"�����!������$���"����1�1��"����47)���������������4"����17������1�������$���4J7 ����E������$���"����1�1��"����47)���������������4"����17������1�������$���4D7 ����E������$�������1��%��������47)���������������44A���1��7������1�������$���4I77����2���47 ����E������$����������"����4"����1�����7)���������������������$���4JB����7 ����E������$����������"����4"����1�����7)���������������������$���4DB����7 ����E������$����������%��������4������7)���������������������$���4IB��=�A���1��4��77 ����E���������1�$�����A�&��!������$���"����1���"����147����)��������"����1��,�9�������^!�9N(����'��N9�����������!�9N���� ���������N,������"�����4�����7 ��������������� ����EE

Wie in Beispiel 5.4 werden hier die Methoden getSQLTypeName(), readSQL() undwriteSQL() benötigt. Mit der Methode readSQL() werden die Attribute des Typsfirma_t in der Reihenfolge gelesen, wie der Typ in der Datenbank definiert wurde:

Page 211: Java in Datenbanksystemen

������� ����� ����������������������������"#$�%&"' ���

-�/�?/���O�?�#/�(����'��4(�����'���A@?/U/��@�?�@�..B�(�����'�����-%��4IL7�@�?�@�..B������������'�7

Zuerst wird der Wert der Spalte firmen_nr (als eine Ganzzahl) mit Hilfe der MethodereadInt() gelesen, danach der Wert der Spalte firmen_name mittels readString(). DerWert der Spalte adresse ist eine Struktur, die folgendermaßen eingelesen wird:

�����'������,�4"�����7������������$����47

Wie auch schon beim Vektor, der die Vornamen eines Autors in Beispiel 5.4 gespeicherthat, haben wir hier das Problem, dass die Struct-Schnittstelle nur lesende Methodenbereitstellt und daher keine Adressdaten verändert werden können. Aus diesemGrund wird eine neue Klasse namens GenericStruct erstellt, welche die Klasse Structimplementiert und einige zusätzliche Methoden zur Veränderung von Struct bereit-stellt. Ähnlich zu GenericArray ist GenericStruct sehr einfach aufgebaut: Es werdenlediglich Variablen zugewiesen oder zurückgegeben und die Struct-Schnittstelleimplementiert. Aus diesem Grund wird auf ihre Implementierung nicht detailliert ein-gegangen. Wichtig ist nur, dass wir mit Hilfe der GenericStruct aus der bereits vorhan-denen, nur lesbaren Adressen-Struktur eine Klasse erstellen, die auch Methoden zumÄndern enthält. Dazu wird der Konstruktor von GenericStruct aufgerufen und dieStruktur des Typs adresse_t übergeben.

Die Methode writeSQL() schreibt alle Daten wieder in der Reihenfolge in den Daten-strom zurück, in dem sie gelesen wurden. Für das Schreiben einer Struktur stellt derDatenstrom die Methode writeStruct() zur Verfügung.

Die Methode processStruct() ist eine reine Hilfsfunktion und gibt alle Daten einerStruktur aus. Dazu gibt diese Methode zuerst mittels getSQLTypeName() den SQL-Namen der Struktur aus und holt sich ihren Inhalt mit der Methode getAttributes().Die Methode wird dann so lange rekursiv aufgerufen, bis keine Struktur mehr gefun-den wird. Es wird dann davon ausgegangen, dass ein Datenwert vorliegt, der ausgege-ben wird. Es ist zu beachten, dass die Funktion von sehr einfachen Strukturen ausgeht,die keine weiteren komplexen Typen (außer Strukturen selbst) enthalten. Für eventuellenthaltene Vektoren wird lediglich deren toString()-Methode aufgerufen. (WeitereTypen könnten durch Hinzufügen einer weiteren if-instanceof-Abfrage abgearbeitetwerden.)

Die get()/set()-Methoden dienen der einfachen Veränderung der Adressenstruktur.Dazu werden die in der Klasse GenericStruct implementierten Hilfsfunktionen aufge-rufen. Die Methode toString() gibt mit Hilfe der Methode processStruct() den Inhaltder Firma aus.

Der folgende Programm-Code in Beispiel 5.5:

���������+�������,�����1��?���+��47 �������49(����'�9B�-��(��@���49��/C�������(����'�977 ������?���+��4���7

Page 212: Java in Datenbanksystemen

��� ������������ ����� �����������������������

erstellt die Verbindung zwischen dem Typ firma_t und dem Java-Objekt firma_t. DieMethode getObject() der Ergebnismenge liefert eine Instanz des firma_t-Objekteszurück, welche mit der darin enthaltenen toString()-Methode ausgegeben wird. Dazuwird das Objekt einfach der println-Anweisung übergeben, welche automatisch dieentsprechende Methode (toString()) aufruft.

Um Daten der Firma zu ändern, wird auf die vorher implementierten get()/set()-Methoden zugegriffen und der Name der Stadt in New York mittels

�(�������"����49@�=����G97

verändert. Eine Instanz der Klasse PreparedStatement schreibt die Änderung in dieDatenbank (weil Informix kein Ändern über das ResultSet erlaubt). Dazu wird mitHilfe von

��������$����4DB(����7

das geänderte Datenbankobjekt aktualisiert. Am Programmende werden noch einmalalle geänderten Reihen ausgegeben, um die Änderungen visuell zu bestätigen.

��$ ���������� ���� ��� �� ���� �� ���� ��� �����

Das Datenbanksystem DB2 der Firma IBM unterstützt folgende objektorientierteErweiterungen:

� benutzerdefinierte Datentypen

� den REF-Operator

� Typ- und Tabellenhierarchien.

Zum Zeitpunkt des Schreibens dieses Buches (Herbst 2001) sind noch keine von denoben genannten Erweiterungen in JDBC implementiert worden.

��1 2�&�// �.�&&���

Die in diesem Buch erläuterten Datenbanksysteme unterstützen in jeweiligen JDBC-Implementierungen verschiedene objektorientierte Erweiterungen und zwar in sehrunterschiedlichem Umfang.

Oracle unterstützt in der JDBC-Schnittstelle alle objektorienterten Erweiterungen, die derDatenbank-Server unterstützt. Mit Hilfe der spezifischen Klasse ( wie OraclePrepared-Statement und OracleResultSet) bietet Oracle Erweiterungen, die über die Funktionalitätvon JDBC API 2.0 gehen. Deswegen kann man sagen, dass Oracle seine Implementierungvon objektorientierten Erweiterungen am weitesten vorangetrieben hat.

Page 213: Java in Datenbanksystemen

()�**��+�))�� ���

Informix hat die meisten objektorientierten Erweiterungen, die der Informix-Serverunterstützt, in JDBC implementiert. Ein Nachteil ist, dass die Änderung einer Instanzder Statement-Klasse (noch) nicht unterstützt wird, was die Programmierung solcherFunktionen komplexer macht.

Die Firma IBM hat die im DB2-Server unterstützten objektorientierten Erweiterungennoch nicht in JDBC implementiert.

Das nächste Kapitel beschreibt viele Fälle, die die Performance von JDBC untersuchen.Es ist gleichzeitig das letzte Kapitel, das sich auf JDBC bezieht.

Page 214: Java in Datenbanksystemen
Page 215: Java in Datenbanksystemen

� ����������� ��������������

In diesem Kapitel werden wir zahlreiche Fälle zeigen, die sich mit den Performance-Aspekten bei JDBC beschäftigen. Zuerst wird eine Einführung zum Thema Perfor-mance gegeben und danach werden mehrere Fälle gezeigt, die Ihnen bei der Verwen-dung von JDBC wichtige Hinweise für die Optimierung von Programmen geben. AmEnde des Kapitels werden wir einige wenige Fälle zeigen, wo wir Performance-Gewinne erwartet, aber bei den Tests keine erzielt haben.

��� ������������������������

Die Verbesserung der Performance ist eine wichtige Aufgabe, die bei der Datenbank-programmierung u.a. folgende Bereiche betrifft:

� die Effizienz des Benutzer-Codes

� das Datenbankmanagementsystem.

Die folgenden Unterabschnitte erläutern die beiden Bereiche.

����� ������������� � ����������� �

Die Art und Weise, wie ein Programm, das auf Daten einer Datenbank zugreift, imple-mentiert ist, kann die Performance eines Systems erhöhen bzw. verschlechtern. Es exis-tieren sehr viele Hinweise, die generell einen guten Programmierstil beschreiben unddie für alle Programmiersprachen gelten.

In diesem Kapitel werden wir u.a. einen spezifischen Fall eines guten Programmier-stils bezüglich der Datenbankprogrammierung erörtern. Der erste und gleichzeitigwichtigste Punkt stellt die optimale Programmierung von Datenbankzugriffen dar.

In Datenbankanwendungen werden häufig Abfragen verwendet, die gleichzeitig vieleReihen einer Tabelle auswählen. In solchen Fällen ist es immer besser, die Ergebnis-menge aller Reihen mit einer Anweisung festzulegen als für jede Reihe einmal die ent-sprechende Anweisung durchzuführen. Der Vorteil der ersten Art der Programmie-rung ist, dass die entsprechende SELECT-Anweisung eine wesentlich geringere

Page 216: Java in Datenbanksystemen

��� ������������ ������������������

Anzahl von E/A-Operationen erfordert und nur einmal vorübersetzt werden muss(siehe Beispiele 6.1 – 6.2).

����! �� ���������������� " ���

Das Datenbankmanagementsystem kann auch die Performance des Systems beeinflus-sen. Die beiden wichtigsten Bereiche des Datenbankmanagementsystems, welche diePerformance erhöhen bzw. verschlechtern können, sind:

� der Optimierer

� die Sperren.

�������������

Die Aufgabe des Optimierers ist es, mehrere Strategien für die Ausführung einer Daten-manipulationsanweisung zu erstellen und danach die mit den niedrigsten Kosten aus-zuwählen. Die Arbeit des Optimierers ist sehr wichtig bezüglich der Performance, weildurch die Auswahl einer falschen Strategie alle betroffenen Anwendungen eineschlechte Performance haben werden. (Weil wir uns in diesem Kapitel mit der Perfor-mance von JDBC-Programmen beschäftigen, wird die Funktionsweise und die Arbeiteines Optimierers nicht weiter verfolgt.)

�������

Sperren stellen das Mittel dar, mit dem der konsistente Zugriff auf Daten für vieleBenutzer ermöglicht wird. Die Auswahl des Datenbankobjektes (Reihe, physikalischeSeite, Tabelle), das gesperrt wird, beeinflusst in hohem Maße die Performance desSystems. Grundsätzlich gilt, dass eine Sperre auf eine Reihe in den meisten Fällen diebeste Performance ermöglicht, weil dadurch der ungehinderte Zugriff auf Daten fürmehrere Benutzer möglich ist.

Die in Kapitel 3 erörterten Isolierungsstufen beeinflussen die Dauer einer Lesesperre.Die Verwendung einer niedrigeren Isolierungsstufe (wie READ UNCOMMITTED bzw.READ COMMITTED) erhöht die Verfügbarkeit der Daten einer Datenbank (auf Kostender Datenkonsistenz).

��! �������#�$#����%������������&� �

Die Performance eines Systems kann nach zwei Kriterien:

� der Ausführungszeit (elapsed time)

� CPU-Zeit

gemessen werden.

Page 217: Java in Datenbanksystemen

������������������������������������ ��

Die Ausführungszeit eines Programms kennzeichnet das Zeitintervall zwischen demStart und Ende seiner Ausführung. Die CPU-Zeit spezifiziert die Zeit, die der Prozes-sor verbraucht hat, um das Programm auszuführen. Wir haben in diesem Kapitel dieAusführungszeit der Programme als Messeinheit verwendet.

Damit die Testergebnisse nicht verfälscht werden, haben wir zwei unabhängige Ver-fahren verwendet, um die Ausführungszeiten zu messen. Zusätzlich dazu wurde jederTest mehrmals (gewöhnlich zehn mal) wiederholt.

Die beiden angewandten Messverfahren sind:

� die Java-Methode currentTimeMillis() der Klasse System

� das Werkzeug Timethis.exe, das Bestandteil von Windows-NT Resource-Kit ist.

Die Methode currentTimeMillis() ist eine statische Methode der Klasse java.lang.System, die die aktuelle Zeit (in Millisekunden) zurückgibt. Dementsprechend habenwir diese Methode zum Beginn und am Ende des zu messenden Programmteils aufgeru-fen und den ersten Wert von dem zweiten subtrahiert. Der folgende Code-Ausschnittzeigt, wie diese Methode für Performance-Messungen verwendet wurde:

������������ ����������������� ���

������������������ ������

�� ���������������� !� "#$���� %���&��'�� �(���� ����������������� ���)�

�����(� ����� ����� ��

Bei der zweiten Messmethode haben wir das Ladeprogramm Timethis.exe verwendet.Dieses Programm misst die gesamte Ausführungszeit einer Anwendung oder einesAnwendungsteils und hat folgende Syntax:

����$� �*�+,-,�*�.�, ��,�

wo Klassenname der Name einer kompilierten Java-Klasse ist.

In den folgenden Abschnitten werden wir die untersuchten Fälle erörtern.

��' ����(���������� ������������������

Einer der wichtigsten Performance-Aspekte stellt die optimale Programmierung vonDatenbankzugriffen dar. In den Datenbankanwendungen aller Arten werden häufigDatenmanipulationsanweisungen verwendet, die gleichzeitig viele Reihen einerTabelle auswählen bzw. ändern. In solchen Fällen ist es immer wesentlich besser, dieErgebnismenge mit einer SQL-Aweisung (SELECT, UPDATE oder DELETE) festzule-gen, als für jede Reihe einmal die entsprechende SQL-Anweisung auszuführen. DerVorteil der ersten Programmierungsart ist, dass eine wesentlich geringere Anzahl vonE/A-Operationen notwendig ist.

Page 218: Java in Datenbanksystemen

��! ������������ ������������������

Das folgende Beispiel zeigt ein JDBC-Programm, das Reihen aus der Tabelle mitarbei-ter mit einer Abfrage liest, die mehrmals (in unserem Programm maximal 9000 mal)übersetzt und ausgeführt wird.

Beispiel 6.1

Finden Sie Daten aller Mitarbeiter, deren Personalnummer vierstellig ist.

���/ ��-���0,���,� �0��������������

�������+,-,� 1��2�

��, �3�"4��

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"��������+B��+H�;A3�:68�(B��+((�

������������5

���������������� ��������������� 0���$�,�"�8��I� �(�+��

������������������,�����-��&����I

�������������� �����������,���,�������

����������������9#��+����,�%����!&"�,��,& �%���JCCC�!&"�,��

��������������"���������BCCC���H�JJJJ���((�

��������������5

����������������� �� ����*���K����� �A/A���2�"�������,�&���

�����������������@LA;A��4�� �(�����

����������������� ��*����

������������������ ������������� G���4���� �(�� ����������B����

������������M��������������������������������

�������������� �����������������

������������� ���� ���

������������ ������� ���

������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� �� (��� ����������������� ���)��4����

�������������(� ������ ����� ��

��������������!& �$�� ,�&���2222222222222222

������������������� ���

Page 219: Java in Datenbanksystemen

������������������������������������ ��"

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6��� � $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

In Beispiel 6.1 wird zuerst die Anzahl der Wiederholungen mit Hilfe der KonstanteREPCOUNT auf 10 gesetzt. Abgesehen vom Aufruf des Dientsprogramms DBUtilsund dem Anfang und Ende der Zeitmessung beinhaltet das Programm als seinenwichtigsten Teil die for-Schleife, wobei die SELECT-Anweisung maximal 9000 malübersetzt und ausgeführt wird. Dieser Programmierstil ist sehr ineffizient, weil die-selbe Anweisung immer von neuem übersetzt wird.

Beispiel 6.2 zeigt die effiziente Art, wie dasselbe Problem gelöst werden kann. Die Effi-zienz wird dadurch erreicht, dass die SELECT-Anweisung nur einmal übersetzt unddanach so oft wie notwendig ausgeführt wird.

Beispiel 6.2

��/ ��-���0,���,� �0�����������

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4 �

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"��������+B��+H�;A3�:68�(B��+((�

������������5

Page 220: Java in Datenbanksystemen

��# ������������ ������������������

����������������� ��������������� 0���$�,�"�8��I� �(�+��

�������������������,�����-��&����I

��������������� �����������,���,�������

�����������������B�!&"�,��"#��JCCC��'�%�,& �%�

���������������� �� ����*���K���� �A/A���2�"�������,�&���

����������������@LA;A��4����A�@AA8�BCCC�!80�JJJJ ��

���������������������� ���� ���,�"����;�$��%����"�

����������������$����� ��*����

�������������������� ������������� G���4��� �(�� ����������B����

�����������������!� �,&�-�����,���B

����������������� �����������������

���������������� ���� ���

��������������� ������� ���

������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(

���������������� ����������������� ���)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���22222222222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I������������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Im Unterschied zum Programm in Beispiel 6.1 wird in Beispiel 6.2 die SELECT-Anwei-sung zuerst einmal vorbereitet und ausgeführt. (In diesem Fall befindet sich dieAbfrage nicht innerhalb einer for-Schleife wie in Beispiel 6.1.) Die anschließendewhile-Schleife beinhaltet nur die next()-Methode, die die Abarbeitung der Reihen derErgebnismenge durchführt.

Die Tabelle 6.1 zeigt die signifikanten Unterschiede, die bei der Messung der Ausfüh-rung der Beispiele 6.1 und 6.2 festgestellt wurden.

)�� ��#�����*��� ������ ���+�,��&��-�� �� ../0�/'!�'0'�1����

���������*��� ������ ���+�,��&��-�� �� ../../�2�'34�1����

$���%%���&�'����������������������������������(�����)���%�� *

Page 221: Java in Datenbanksystemen

������������+��+������������������ *�+�������������,-���.�������� ���

��0 �����������%��%������������� ��#�%������������+5,��-�� ���

Wie wir schon in Kapitel 4 erläutert haben, ist die Statement-Schnittstelle die Basis-schnittstelle aller Klassen, die für die Erstellung der SQL-Anweisungen verwendetwerden. Dabei benutzt sie die Methode createStatement() um SQL-Anweisungen zuverarbeiten.

In diesem Abschnitt wird gezeigt, dass die Verwendung der createStatement()-Methode für solche SQL-Anweisungen, die mehrmals in einem Programm verwendetwerden, generell die Performance der Anwendung verschlechtern, weil die MethodecreateStatement() jedesmal die Anweisung von neuem vorübersetzt.

Beispiel 6.3 zeigt die Verwendung der createStatement()-Methode für das Einfügenvon 5000 Reihen in die Tabelle mitarbeiter.

Beispiel 6.3

��A��"#���-���OCCC��'�%�� �,�� �$

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4�� 4 �,�

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"���������B���H�;A3�:68�(B���((�

���������������5

��������������������� ��������������� 0���$�,�"�8��I� �(����

�����������������������,�����-��&����I

���������������� �����������,���,�������

��������������������OCCC��,�%��������� �,�� �$��!&"�,�

����������������������"#����0, ���,����������OCCC�*�-���&� �%�

����������������"��������+BCCCB��+H�BOCCB��+((�

����������������5

����������������������� ����*���6��,��� 78�A;��78�:����,�&���

Page 222: Java in Datenbanksystemen

��� ������������ ������������������

������������������������-,�� �� �(�+2��(� �PL�&��P��P.�,� P�P,QP� ���

������������������������� ������������� G��;�$�����"���I� �(

�������������������������+�BCCCC����

����������������M��������������������������������

������������������ �����������������

����������������� ���� ���

���������������� ������� ���

��������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���2222222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I���������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

In Beispiel 6.3 werden innerhalb einer for-Schleife 5000 Reihen in die Tabelle mitarbei-ter eingefügt. Dabei wird die INSERT-Anweisung 5000 mal vorübersetzt und danachausgeführt. Auf diese Art und Weise wird die angegebene Anweisung jedesmal vomDatenbank-Server als eine neue SQL-Anweisung behandelt, obwohl es sich um die-selbe Anweisung handelt.

Diese Arbeitsweise ist nicht optimal. Sie kann optimiert werden, indem die mehrfacheAusführung einer INSERT-Anweisung so behandelt wird, dass die Anweisung nureinmal vorübersetzt und danach so oft wie notwendig ausgeführt wird. Dies kann mitder prepareStatement()-Methode der Connection-Schnittstelle realisiert werden.

Beispiel 6.4 zeigt die JDBC-Anwendung, die identisch zum Beispiel 6.3 ist und die Vor-bereitung der SQL-Anweisung mit Hilfe der Methode prepareStatement() durchführt.

Beispiel 6.4

��A��"#���-���OCCC��'�%�����,�� �$

�������+,-,� 1��2�����������������������������

��, �3�"4�� 4���

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

Page 223: Java in Datenbanksystemen

������������+��+������������������ *�+�������������,-���.�������� ��/

���� �,����3��,����,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

���������������������,�� �$ ���,�����-��&����I

���������������� ������������,���,����� �� �������

��������������������,�&����-,�� ���R��PL�&��P��P.�,� P�P,QP� ��

������������������OCCC��'�%����,�� �$���"#����0, ���,����

��������������������������B*�-��#&� �%�

����������������"��������+BCCCB��+H�BOCCB��+((�

����������������5

�������������������� ���� �7���B�+2���

�������������������� ����*���6��,����

���������������������� ������������� G��;�$�����"���I

��������������������� �(��+�)�BCCCC����

����������������M��������������������������������

������������������ �����������������

����������������� ���� ���

���������������� ������� ���

��������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Page 224: Java in Datenbanksystemen

��0 ������������ ������������������

In Beispiel 6.4 wird die INSERT-Anweisung mit Hilfe der prepareStatement()-Methode nur einmal vorübersetzt und danach so oft wie notwendig ausgeführt. Die zuändernden Werte werden mit Hilfe der setXXX-Methoden (in unserem Fall handelt essich um die setInt()-Methode) zugewiesen.

Tabelle 6.2 zeigt die Unterschiede, die bei der Messung der Ausführung der Beispiele6.3 und 6.4 festgestellt wurden.

��3 +������� �6�#��+�������� ��

Ein Scroll- und ein Nicht-Scroll-Cursor zeigen signifikante Unterschiede in Bezug aufihre Funktionalität. Der wichtigste Unterschied ist, dass letzterer die Reihen einerErgebnismenge immer sequenziell lesen kann, während der erste das Lesen der Reihenwahlfrei, d.h. in beliebiger Reihenfolge durchführen kann. (Für die ausführlicheBeschreibung beider Cursor-Arten siehe Kapitel 4.)

Weil die erste Cursor-Art sehr einfach ist, (und nur das sequentielle Lesen mit Hilfeeiner einzigen Methode next() ermöglicht), ist zu erwarten, dass diese auch performan-ter sein sollte als die Verwendung des Scroll-Cursors, wo beliebige »Sprünge« ab deraktuellen Reihe der Ergebnismenge möglich sind.

Folgende drei Programme zeigen die Tests, die wir mit einem Nonscroll-Cursor undder Methode next() gemacht haben (Beispiel 6.5), sowie mit einem Scroll-Cursor undden Methoden absolute() (Beispiel 6.6) und relative() (Beispiel 6.7). In allen diesen Pro-grammen haben wir 20 Durchläufe mit insgesamt 500 Reihen durchgeführt.

Beispiel 6.5

��/ ��-���0,���,� �0���$������������ ��

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4���4 �����

7��-� ���������#�%������������86+�9&��-�� �� ../.�/3'�3�!�1����

7��-� ��������%������������86+�9&��-�� �� ../../34��!3�1����

$���%%���&�'�)����������������� *�+�������������.��������'�����)���%�� *

�������

Der Nachteil eines Scroll-Cursors in Bezug auf die Performance liegt oft in derGröße des Puffers. In vielen Fällen ist die Ergebnismenge einer Abfrage größer alsder zur Verfügung stehende Puffer. Bei den »Sprüngen«, die der Cursor verursacht,kann es passieren, dass die entsprechende Reihe außerhalb des Puffers steht, washäufige Änderungen des Pufferinhalts nach sich zieht und damit die Performancedes Programms verschlechtert.

Page 225: Java in Datenbanksystemen

� �%%������1� *��� �%%������ ��2

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���SC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

�������������������,�����-��&����I

��������������� �����������,���,�������

���������������"���������C���H�;A3�:68����((�

���������������5

��������������������� ��������������� 0���$�,�"�8��I� �(����

���������������������!&"�,��"#��OC��'�%

�������������������� �� ����*���K���� �A/A���2�"�������,�&���

��������������������@LA;A��4����A�@AA8�BCCC�!80�BOCC ��

�������������������������� ���� �����",����� ������ ��������� ���

���������������������,�"����;�$��%����"�

��������������������$������ ��*�������

������������������������ ��������������� �4��� �(�� ����������B�

����������������������(� G���4�,�� (�� ����������S����

������������M

������������ ������� ���

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���22222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Page 226: Java in Datenbanksystemen

��� ������������ ������������������

In Beispiel 6.5 wird ein Nicht-Scroll-Cursor für eine Abfrage, die maximal 500 Reihenliefert, definiert. Alle Reihen der Ergebnismenge werden anschließend mit Hilfe derexecuteQuery()-Methode sequenziell gelesen, und ihre Werte werden mit Hilfe derMethode next() innerhalb einer while-Schleife ausgegeben.

Beispiel 6.6 zeigt die Implementierung derselben Problematik mit Hilfe eines Scroll-Cursors und der Methode relative().

Beispiel 6.6

��/ ��-���0,���,� �0��������,��-����������� ��

�������+,-,� 1��2�

��, �3�"4��4 �����

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���SC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������������� ��C����C������C�

����������������,�����-��&����I

������������ ����

�������������������,���,������ ��T3A4��;://478�A8�7�7>A

��������������� ��:8�6;4;A!04:8/T��

������������"���������C���H�;A3�:68����((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

�������������������!&"�,��"#��OCB��'�%

����������������� �� ����*���K���� �A/A���2�"�������,�&���

�����������������@LA;A��4����A�@AA8�BCCC�!80�BOCC ��

����������������� ��*����

����������������������� �,& ��������� ���,�"����;�$��%����"�

����������������"���������C���HOCB���((�

����������������5

��������������������� ���,��-�B��

���������������������� ��������������� �4��� �(�� ����������B��(

��������������������� G���4�,�� (�� ����������S����

����������������M

������������M�

Page 227: Java in Datenbanksystemen

� �%%������1� *��� �%%������ ��

������������ ������� ���

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���222222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

In Beispiel 6.6 wird ein Scroll-Cursor für eine Abfrage, die maximal 500 Reihen liefert,definiert. Im Unterschied zu Beispiel 6.5, wo die Methode next() innerhalb einer while-Schleife definiert wurde, wird in Beispiel 6.6 eine for-Schleife, die die Methode rela-tive() für das Lesen der Reihen der Ergebnismenge enthält, implementiert.

Beispiel 6.7 zeigt die Implementierung derselben Problematik mit Hilfe eines Scroll-Cursors und der absolute()-Methode.

Beispiel 6.7

��/ ��-���0,���,� �0��������,��-����������� ��

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4,& 4 �����

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���SC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

Page 228: Java in Datenbanksystemen

��! ������������ ������������������

������������������� ��C����C������C�

�����������������B�

����������������,�����-��&����I

������������ ����

�������������������,���,������ ��T3A4��;://478�A8�7�7>A�

�������������� ��:8�6;4;A!04:8/T��

������������"���������C���H�;A3�:68����((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

�������������������!&"�,��"#��OCB��'�%

����������������� �� ����*���K���� �A/A���2�"�������,�&���

�����������������@LA;A��4����A�@AA8�BCCC�!80�BOCC ��

����������������������� �,& ��������� ���,�"����;�$��%����"�

����������������"��������B���HOCS���((�

����������������5

��������������������� �,& ��������

���������������������� ��������������� �4��� �(�� ����������B��(

��������������������� G���4�,�� (�� ����������S����

����������������M

������������M�

������������ ������� ���

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���2222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Beispiel 6.7 ist identisch mit Beispiel 6.6, benutzt aber anstatt der relative()-Methodedie Methode absolute().

Die Vermutung, dass ein einfacher (Nonscroll-) Cursor performanter als ein Scroll-Cur-sor ist, hat sich beim Testen bestätigt. Tabelle 6.3 zeigt die Unterschiede, die bei derMessung der Ausführung der Beispiele 6.5 -6.7 festgestellt wurden.

Page 229: Java in Datenbanksystemen

����3*����������,-���.�������������%����� * ��"

��� �� �$#���� ���+5,��-�� ���������� ���� *

Die Statement-Schnittstelle unterstützt die Methoden execute() und executeBatch(),mit denen SQL-Anweisungen ausgeführt werden können. Der wesentliche Unter-schied zwischen diesen beiden Methoden ist, dass die erste jede Anweisung einzelnübersetzt und anschließend ausführt, während die zweite eine Gruppe von SQL-Anweisungen gleichzeitig bearbeitet.

Die executeBatch()-Methode wurde als Teil der batch-Verarbeitung mit JDBC API 2.0eingeführt. (Das Wort batch-Verarbeitung kennzeichnet eine Gruppe von Anweisungenoder Transaktionen, die unabhängig von der Benutzer-Interaktion mit dem Systemerfolgen.)

Bei der Ausführung einer einzelnen SQL-Anweisung werden (im Allgemeinen) fol-gende Schritte ausgeführt:

1. die Anweisung wird vorbereitet

2. die Parameter werden an die entsprechenden Spalten gebunden

3. die Anweisung wird ausgeführt

4. Schritte 2 und 3 werden (falls notwendig) wiederholt.

Diese Art von Verarbeitung ist ineffizient falls mehrere SQL-Anweisungen hinterein-ander übersetzt und ausgeführt werden, weil ein JDBC-Programm für jede einzelneAnweisung mehrmals die Verbindung zum Datenbanksystem herstellen muss. Diewesentlich effizientere Methode ist mit der batch-Verarbeitung gegeben, wo folgendeSchritte ausgeführt werden:

1. die Anweisung wird vorbereitet

2. die Parameter werden an die entsprechenden Spalten gebunden

3. das Ergebnis wird dem batch angehängt

4. Schritte 2 und 3 werden (falls notwendig) wiederholt

5. batch wird ausgeführt.

Der Vorteil der batch-Verarbeitung ist offensichtlich: Die Verbindung zum Datenbank-system erfolgt nicht so oft wie bei der Abarbeitung jeder Anweisung separat.

7��-� ������ �6�#��+�������� �� ../.��:3.�1����

7��-� ������ �+�������� �� �� �1��#� ��������%�;< ../.4�3�!�1����

7��-� ������ �6�#��+�������� �� �� �1��#� ���� �����;< ../�.�!.'�1����

$���%%���&/'�)���%�� *�+��+��� *��������� �%%������1�� �%%�������$4���

Page 230: Java in Datenbanksystemen

�/# ������������ ������������������

Beispiel 6.8 zeigt die Verarbeitung jeder einzelnen SQL-Anweisung, während Beispiel6.9 dieselbe Aufgabe mit der batch-Verarbeitung löst.

Beispiel 6.8

���$�",�$���,����

�������+,-,� 1��2�

��, �3�"4�����4 �,����

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

��������������������",�$ ����������+��� ��������

�������������������,�����:&+��

����������������"��������+C��+H�OC��+((�

����������������5

�������������������� �����������,���,�������

�������������������� ����*���K����� �A/A����4���"�������,�&���

����������������������$��,&�4����P,BP ��

���������������������� ��������������� ��,�������I� �(�+��

�������������������� ������� ���

����������������M��������������������������������

������������������ �����������������

������������M

��

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���222222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

Page 231: Java in Datenbanksystemen

����3*����������,-���.�������������%����� * �/�

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

In Beispiel 6.8 werden mit Hilfe der executeUpdate()-Methode zuerst eine Anzahl vonReihen in die Tabelle mitarbeiter eingefügt und diese danach einzeln geändert. Bei-spiel 6.9 verwendet Methoden der batch-Verarbeitung, um die Verarbeitung einerAnweisungsgruppe performanter auszuführen.

Beispiel 6.9

��!��� �����,� ��,��$�,� "#$��

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4&,��$

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

����������������+�

���������������DE��,��$����������

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

��������������������,�����-��&����I

���������������� �����������,���,�������

������������������U������-���!��� �����

������������������B���$����I�78�A;��!��� ����

����������������"����+SCCCC��+HSCCSO��+((�

����������������������� ����,���,��$�� 78�A;��78�:����,�&���

������������������������>!/6A��� �(�+�(� �PL,� P�P�� ���,��P�P,SP� ���

Page 232: Java in Datenbanksystemen

�/� ������������ ������������������

������������������S���$����I�630!�A�!��� ����

����������������"����+SCCCC��+HSCCSO�+((�

����������������������� ����,���,��$�� 630!�A����,�&���� ���4��

������������������������(��BCCCC�(�+��(� ��$���4�� (�+���

������������������ ��������������� !� "�$���� ��,��$ �����OC

�����������������!��� ���� ��

�����������������,��$������� ����*����,��$�����������

���������������� ������� ���

�������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���2222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Im Unterschied zu Beispiel 6.8, wo die executeUpdate()-Methode innerhalb einer for-Schleife verwendet wird, benutzt das JDBC-Programm in Beispiel 6.9 die addBatch()-und executeBatch()-Methoden, um eine Anzahl von Reihen in die Tabelle mitarbeitereinzufügen, und diese danach zu ändern. Dabei wird das Einfügen und Ändern derReihen als ein batch zusammengefasst.

Tabelle 6.4 zeigt die Unterschiede, die bei der Messung der Ausführung der Beispiele6.8 und 6.9 festgestellt wurden.

��: �=��������� �����������&�� ������

JDBC unterstützt die setAutoCommit()-Methode, die darüber entscheidet, ob eineAnwendung implizite oder explizite Transaktionen verwendet. Nach dem Herstelleneiner Verbindung befindet sich jede Datenbank, gemäß der JDBC-Spezifikation,

9��#��-�� ������������������ ../�4�:.'�1����

7��-� ��� ������ *�7���������� ../.3�:�3�1����

$���%%���&0'�)���%�� *��������#�����1� *�����#�)�����������

Page 233: Java in Datenbanksystemen

56�%������������%������$����������� �//

zunächst in dem so genannten AutoCommit-Modus. Der AutoCommit-Modus bedeu-tet, dass der Parameter der Methode setAutoCommit() der Klasse Connection aufrichtig (true) gesetzt ist und damit jede einzelne Anweisung als separate Transaktionbehandelt wird. (Dieser Modus wird auch impliziter Modus genannt.)

Diese Art von Transaktionsbildung ist sehr oft ineffektiv, weil die Sperren, die jedeTransaktion für die Abgrenzung der verwendeten Datenbankobjekte benutzt, zu jederAnweisung gesetzt und an ihrem Ende freigegeben werden müssen.

Durch den Aufruf der setAutoCommit()-Methode und der Übergabe des Wertes falsekann der implizite Modus in den expliziten geändert werden. Danach müssen alleTransaktionen durch den Aufruf der Methode commit() explizit bestätigt bzw. durchdie Methode rollback() zurückgesetzt werden.

Beispiel 6.10 zeigt die Verarbeitung im AutoCommit- d.h. im impliziten Modus, wäh-rend Beispiel 6.11 dieselbe Aufgabe mit Hilfe der commit()-Methode löst.

Beispiel 6.10

����,� ,�����������!���������

�������+,-,� 1��2��������������������������������������������������������������������������������

��, �3�"4,���������

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

��������������!���������� �� �,��,���'V���,���-���

���������������� �!�����������������

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

������������������ ��������������� ��,� ,�����������

�����������������!�������������� ��

��������������������,�����-��&����I

���������������� �����������,���,�������

������������������A�����,� ,������,�"&,��

Page 234: Java in Datenbanksystemen

�/0 ������������ ������������������

����������������"��������+BCCC��+HBOCB��+((�

����������������5

���������������������� ������������� G���,�&����,�%� �(��+��

���������������������BCCC���

�������������������� ����*���6��,�� 78�A;��78�:����,�&���

���������������������>!/6A�� (+( �PL,� P�P�,��P�P,BP� ��

����������������M

������������������ ���������������������������������������������

������������������ ��������������� A��"����-���OCC��,�%� ��

���������������� ������� ���

������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���22222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I����������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

In Beispiel 6.10 wird der AutoCommit-Modus auf true gesetzt und damit jede einzelneAnweisung im Programm als eine einzelne Transaktion behandelt. Die for-Schleifeführt die INSERT-Anweisung 500 mal aus. Damit beinhaltet das Programm insgesamt500 Transaktionen.

Beispiel 6.11 zeigt das entsprechende Programm mit der expliziten Transaktionsbil-dung.

Beispiel 6.11

����,� ,��������$��!���������

�������+,-,� 1��2����������������������������������������

��, �3�"4��,���������

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

Page 235: Java in Datenbanksystemen

56�%������������%������$����������� �/2

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

��������������!���������� �� �,��,���'V���,���-�����W�,���-���

���������������� �!�����������",� ���

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

������������������ ��������������� ��,� ,�����������

�����������������!����������",� � ��

��������������������,�����-��&����I

���������������� �����������,���,�������

������������������A�����,� ,������,�"&,��

����������������"��������+BCCC��+HBOCB��+((�

����������������5

����������������������� ������������� G���,�&����,�%� �(��+��

����������������������BCCC���

��������������������� ����*���6��,�� 78�A;��78�:����,�&���

����������������������>!/6A�� (+( �PL,� P�P�,��P�P,BP� ��

����������������M

������������������ ���������������������������������������������

������������������ ��������������� A��"����-���OCC��,�%� ��

�����������������������������

���������������� ������� ���

������������M

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I����������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

Page 236: Java in Datenbanksystemen

�/� ������������ ������������������

��������M

����M��A���-����,��

M

In Beispiel 6.11 wird der AutoCommit-Modus auf false gesetzt. Damit wird mit Hilfeder commit()-Methode jede Transaktion explizit definiert. Die for-Schleife führt dieINSERT-Anweisung 500 mal aus, und weil die commit()-Methode außerhalb derSchleife ist, werden alle 500 Anweisungen zu einer einzigen Transaktion gehören.

Tabelle 6.5 zeigt die Unterschiede, die bei der Messung der Ausführung der Beispiele6.10 und 6.11 festgestellt wurden.

��2 +��������(�>����

Alle Abfragen und Datenmodifikationsanweisungen werden mit Hilfe von sogenann-ten Anweisungsobjekten erstellt. Anweisungsobjekte werden von der Statement-Schnittstelle (oder einer seiner Subkomponenten) implementiert und von Methodender Connection-Schnittstelle erzeugt.

Anweisungsobjekte sind bei vielen Treibern kostspielige Ressourcen, deren Erzeugenviel Speicher oder Rechenzeit kostet. Das Erzeugen einer großen Anzahl von solchenObjekten (beispielsweise beim Durchlaufen einer Schleife) sollte deswegen vermiedenwerden.

Im Folgenden haben wir die Performance zweier Programme getestet, von welchendas erste 500 Anweisungsobjekte (innerhalb einer Schleife) erstellt, während daszweite für dieselbe Aufgabe ein einziges Objekt verwendet.

Beispiel 6.12 erzeugt je ein Anweisungsobjekt für jede im Programm existierendeAnweisung.

Beispiel 6.12

��A��",�$ ���,����

�������+,-,� 1��2������������

��, �3�"4 �,����

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

���$���%��3..�9��#�����������������;3..�&�� ������< ../.3/�.4�1����

���$���%��3..�9��#���#�������������;��&�� �����< ../�2��0.�1����

$���%%���&2'�)���%�� *�+����%������������6�%�������$�����������

Page 237: Java in Datenbanksystemen

�����������7���� �/

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������ �����������,���,�������

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

��������������������",�$ ����������+��� ��������

�������������������,�����:&+��

����������������"��������+C��+H�OC��+((�

����������������5

�������������������� ����*���K����� �A/A����4���"�������,�&���

����������������������$��,&�4����P,BP ��

���������������������� ��������������� ��,�������I� �(�+��

����������������M��������������������������������

������������������ �����������������

������������M

������������ ������� �����

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���22222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I����������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Beispiel 6.13 erzeugt ein einziges Anweisungsobjekt für alle im Programm verwende-ten Anweisungen.

Page 238: Java in Datenbanksystemen

�/! ������������ ������������������

Beispiel 6.13

���$�",�$���,����

�������+,-,� 1��2�

��, �3�"4�����4 �,����

5

���� �,����"��,������0�����0�6��� �789:;�7<�

������&�=�����>,��,&���"#��0��?����""222

���� �,������������������������

���� �,������,����� ����������

���� �,����; ������� �������

������2222222222222222222222222222222222222

�������!�%,$�����@���$������

���� �,����"��,������;A3�:68���BC�

������&���� �,����-�����,����������,��-DE�

����5

���������"��F0�6��� �����0,�,&, 0��-��0������������

���������"��������0�6��� �������0,�,�, �0�������������������

�����������

��������5

�������������� ��������������� >�&�������%��0��:.G� ��

��������������!�",�� %��������"#��?��� ���

������������������4������� ����������������� ���

������������"���������B���H�;A3�:68�(B���((�

������������5

������������������ ��������������� 0���$�,�"�8��I� �(����

��������������������",�$ ����������+��� ��������

�������������������,�����:&+��

����������������"��������+C��+H�OC��+((�

����������������5

�������������������� �����������,���,�������

�������������������� ����*���K����� �A/A����4���"�������,�&���

����������������������$��,&�4����P,BP ��

���������������������� ��������������� ��,�������I� �(�+��

�������������������� ������� ���

����������������M��������������������������������

������������������ �����������������

������������M

��

�������������� ��������������� 0��?����""��,�����,��

��������������������������� ��� �(���� ����������������� ��

�������������)��4�����(� ������ ����� ��

��������������!& �$�� ,�&���222222222222222222222222222

������������������� ���

��������M

����������!� "#$����$�N0���9$��&$,������I�������������

����������,����K/���$������"��-��������K/A*������

���������,��$��K/A*��������

��������5

������������0�6���� $���K/A*���������

��������M

Page 239: Java in Datenbanksystemen

8������ *���9:%%��*���������� ��8����� *���� �/"

���������,��$�A*��������5

�������������� ��������������� G�����9$��������������G� ��

��������������������,����,����

��������M

����M��A���-����,��

M

Tabelle 6.6 zeigt die Unterschiede, die bei der Messung der Ausführung der Beispiele6.12 und 6.13 festgestellt wurden.

��4 ?��� �#���@A�����#������������?��� #�� �

Neben den oben angegebenen haben wir weitere Fälle untersucht, die beim Vergleichkeinen Performance-Vorteil (für die eine oder andere Programmierart) gebracht haben.Folgende Unterabschnitte beschreiben skizzenhaft diese Fälle.

��4�� ����1��#� �� ��@��#�������;<

JDBC API 2.0 unterstützt u.a. eine Methode der Klasse ResultSet, die Performance-Vorteile mit dem Scroll-Cursor bringen soll, falls die Richtung der Abarbeitung vonReihen der Ergebnismenge im voraus bekannt ist. Diese Methode heißt setFetchDirec-tion() und gibt dem Benutzer die Möglichkeit, dem Treiber die Richtung der Abarbei-tung der Reihen der Ergebnismenge mitzuteilen. Dementsprechend können dieserMethode drei Werte:

� ResultSet.FETCH_FORWARD

� ResultSet.FETCH_REVERSE

� ResultSet.FETCH_UNKNOWN

zugewiesen werden.

Mit dem ersten Wert (FETCH_FORWARD) wird dem Treiber mitgeteilt, dass die Rei-hen der Ergebnismenge stets von oben nach unten abgearbeitet werden. Mit dem zwei-ten Wert wird die umgekehrte Abarbeitung der Reihenmenge festgelegt, während derdritte Wert dem Treiber signalisiert, dass die Richtung der Abarbeitung von Reihenunbekannt ist.

In dem Vergleichsfall haben wir zwei Programme erstellt, die beide die Ergebnismengein umgekehrter Reihenfolge (von unten nach oben) gelesen haben. Das eine Programm

7��-� ��%��>�������(�>�����$��>� ���-�� �� .�/0./�3��1�����

7��-� ��%��������-�� �� ��>�����$��������-�� ���� .�/!�/:�2�1����

$���%%���&�'������������7����'�����)���%�� *

Page 240: Java in Datenbanksystemen

�0# ������������ ������������������

wurde mit dem Wert FETCH_REVERSE und das andere mit dem Wert FETCH_UNKNOWN programmiert. Die Performance-Unterschiede der beiden Programmewaren nicht signifikant, was als Hinweis dienen kann, dass diese Funktionalität von denverwendeten Treibern (Oracle, DB2 und Informix) z.Zt. nicht unterstützt wird.

��4�! ����1��#� �� ��@��#+���;<

Der Puffer, in dem eine Ergebnismenge gespeichert wird, kann generell nur einen ein-geschränkten Teil des Arbeitsspeichers belegen. Aus diesem Grund kann ein Systemgewöhnlich nur einen Teil der Ergebnismenge einer Abfrage (besonders wenn dieMenge sehr groß ist) im Puffer speichern. Das Ausleeren des Puffers und das Holeneines anderen Teils der Ergebnismenge verursacht Performance-Verluste, die destohöher sind je öfter die Änderung des Pufferinhalts vom System durchgeführt wird.(Einen weiteren Grund für den Performance-Verlust könnte ein Scroll-Cursor verursa-chen, der »große Sprünge« innerhalb der Ergebnismenge macht und dadurch dasSystem zwingt, bei (fast) jedem Zugriff auf die Reihen unterschiedliche Teile der Rei-henmenge zu laden.)

Ein weiterer Grund für die Verbesserung der Performance durch die Einschränkungder Ergebnismenge liegt darin, dass dadurch nur ein eingeschränkter Teil der Ergeb-nismenge vom Server zum Client geschickt werden muss. (Falls man nur die ersten 50Reihen einer 1000-Reihen große Ergebnismenge sehen will, wird die Performance desSystems signifikant verbessert, weil 950 Reihen überhaupt nicht übers Netz gesendetwerden müssen.)

Die setFetchSize()-Methode hat Ähnlichkeiten mit der Methode setFetchDirection(),weil sie dem Treiber auch gewisse Empfehlungen im voraus gibt, die zur Verbesserungder Performance führen sollen. Diese Methode liefert eine Ganzzahl als Rückgabewert,die die tatsächliche Größe der zur Bearbeitung stehenden Reihen vom Anfang derErgebnismenge spezifiziert. (Der Wert 0 ist Standardwert und stellt fest, dass dieAnzahl der zur Bearbeitung stehenden Reihen unbekannt ist.)

In dem Vergleichsfall haben wir zwei Programme erstellt. Bei dem ersten Programmwurde dem Treiber mitgeteilt, dass nur einige wenige Anfangsreihen der Ergebnis-menge gelesen werden, während beim zweiten Programm der Rückgabewert derMethode auf Null gesetzt wurde. Die Performance-Unterschiede der beiden Pro-gramme waren nicht signifikant, was als Hinweis dienen kann, dass diese Funktionali-tät von den verwendeten Treibern z.Zt. nicht unterstützt wird.

Page 241: Java in Datenbanksystemen

;������������ �0�

���. B� ������ ��

Die von uns untersuchten Fälle können in zwei Gruppen unterteilt werden:

� unterschiedliche Programmierarten

� Verwendung verschiedener Sprachmittel bei JDBC

Wie aus den Performance-Vergleichen zu sehen ist, können durch die Verwendung desoptimalen Programmierstils die höchsten Performance-Gewinne erzielt werden.

Das nächste Kapitel bildet den Anfang eines neuen Buchteils, der sich mit SQLJ befasst.

Page 242: Java in Datenbanksystemen
Page 243: Java in Datenbanksystemen

������������

Page 244: Java in Datenbanksystemen
Page 245: Java in Datenbanksystemen

� ����������

Im ersten Teil dieses Kapitels werden wir etwas über die Einbettung der SQL-Spracheim Allgemeinen sagen. Das ist aus zwei Gründen notwendig: erstens, um ein generel-les Bild bei der Einbettung zu geben und zweitens, um grundsätzliche Unterschiedezwischen SQLJ und allen anderen eingebetteten Sprachen (wie ESQL/C++, ESQL/Ada usw.) zu zeigen. Der Teil des Kapitels, der sich mit SQLJ befasst, zeigt verschie-dene Möglichkeiten, wie diese Programmierschnittstelle verwendet werden kann.Zuerst wird die Implementierung einer einfachen DDL-Anweisung gezeigt, unddanach die Programmierung der SELECT-Anweisung (mit und ohne Iterator). DesWeiteren werden Beispiele mit einem FOR UPDATE-Iterator und die Einbettung derAufrufe in eine gespeicherte Prozedur vorgestellt.

��� ����������������������������������� !�����

Die Notwendigkeit, die SQL-Sprache einzubetten, ergibt sich daraus, dass es sich beidieser Sprache um eine rudimentäre (non computational complete) Programmiersprachehandelt, d.h. eine Sprache die nicht allein ausreicht, um komplexe Datenbankanwen-dungen zu schreiben.

Eine Möglichkeit, Datenbankanwendungen zu schreiben, bietet die Einbettung derSQL-Sprache in eine prozedurale Programmiersprache wie C und C++. Dabei wird einVorübersetzer verwendet, der jede SQL-Anweisung übersetzt. Nach der Vorüberset-zerphase wird ein Programm mit einem einheitlichen Code erzeugt, das anschließendübersetzt werden kann. (Die prozedurale Programmiersprache, in die SQL eingebettetwird, wird Host-Sprache genannt.)

�������

Generell existiert auch eine zweite Möglichkeit, Datenbankanwendungen zu imple-mentieren. Sie heißt CLI (Call Library Interface). Der wichtigste Unterschied zwi-schen diesen zwei Methoden (Einbettung und CLI) ist, dass für die Einbettung einVorübersetzer verwendet wird. Die in Kapitel 4 beschriebene DatenbankspracheJDBC ist ein Beispiel für CLI.

Page 246: Java in Datenbanksystemen

��� ������������� ��

����� "���#���������������$�%��������

Innerhalb eines Datenbankprogramms, das mit Hilfe der Einbettung der SQL-Spracheimplementiert ist, befinden sich zwei verschiedene Arten von Anweisungen:

� Anweisungen der SQL-Sprache

� Anweisungen der Host-Sprache.

Damit ein Vorübersetzer die eingebetteten SQL-Anweisungen von den Anweisungender Host-Sprache unterscheiden kann, ist es erforderlich, alle SQL-Anweisungenbesonders zu kennzeichnen. Dabei muss sowohl der Anfang als auch das Ende einerSQL-Anweisung gekennzeichnet werden.

Bei verschiedenen Host-Sprachen existieren unterschiedliche Notationen für eingebet-tete SQL-Anweisungen. Folgende Übersicht zeigt diese Unterschiede:

Anfang der Anweisung:

�������������� ����������������������������������������������� ����

Ende der Anweisung: (unterschiedlich für verschiedene Sprachen)

�� ! ������""������#$%�������&'&�

����& '(���)��������

In einem Datenbankprogramm werden am häufigsten die DML-Anweisungen (SELECT,UPDATE, INSERT und DELETE) verwendet. Jede dieser Anweisungen ermöglicht mitHilfe von Variablen den Datenaustausch zwischen dem Anwendungsprogramm einer-seits und der Datenbank andererseits. In einer eingebetteten SQL-Anweisung werdensolche Variablen Host-Variablen genannt. (Neben dem Begriff Host-Variablen existiertauch der Begriff des Host-Ausdrucks, der komplexer als eine Host-Variable ist, weildabei eine oder mehrere Variablen innerhalb eines Ausdrucks geschrieben werden kön-nen.)

Host-Variablen dienen im Allgemeinen als Zielvariablen einer Abfrage bzw. könnenanstelle einer Konstante in den DML-Anweisungen verwendet werden. Sie könnennur die Datentypen haben, die in der entsprechenden Host-Sprache erlaubt sind.

�������

Manche Host-Sprachen wie C und C++ unterstützen zusätzlich zu den Host-Varia-blen auch die sogenannten Indikator-Variablen. Weil SQLJ diese Variablen nichtkennt, werden wir sie in diesem Buch nicht näher beschreiben.

Page 247: Java in Datenbanksystemen

�������������� ������������������������ ���

Host-Variablen können u.a. in folgenden Klauseln erscheinen:

� INTO-Klausel einer SELECT bzw. FETCH-Anweisung

� WHERE-Klausel

� HAVING-Klausel

� SET-Klausel der UPDATE-Anweisung

� VALUES-Klausel der INSERT-Anweisung.

����* ���������������$�%�����������������+���(�

Ein Problem, das generell zwischen der SQL-Sprache und einer Host-Sprache existiert,ist, dass SQL eine mengenorientierte und alle Host-Sprachen satzorientierte Sprachensind. Der Begriff »mengenorientiert« heißt, dass eine einzige SQL-Anweisung (SEL-ECT z.B.) eine Menge von Reihen auf einmal bearbeitet, wobei der Benutzer in derRegel nicht weiß, wie viele Reihen eine solche Anweisung lesen bzw. ändern wird.

Im Unterschied zu SQL können Host-Sprachen nicht gleichzeitig mehrere Datensätzebearbeiten, sondern holen sich immer einen Datensatz nach dem anderen. (SolcheSprachen werden dementsprechend satzorientiert genannt.) Damit der Unterschiedzwischen SQL und einer Host-Sprache überbrückt werden kann, wird ein Datenpufferbenutzt, in welchem dann alle Ergebnisreihen einer SQL-Anweisung gespeichert wer-den. Der Puffer wird mit einem Zeiger verbunden, der für die Abarbeitung der Reihenim Puffer verwendet wird. Der Zeiger wird Cursor genannt.

Um einen Cursor in einem Programm zu benutzen, muss generell:

� der Cursor deklariert werden

� der Cursor geöffnet werden

� die Ergebnismenge satzweise abgearbeitet werden

� der Cursor geschlossen werden.

�������

Die Verarbeitung einer Ergebnismenge bei SQLJ ist, wie wir noch sehen werden,teilweise anders als bei anderen eingebetteten Sprachen. SQLJ verwendet Iteratorenanstatt eines Cursors.

Page 248: Java in Datenbanksystemen

��� ������������� ��

����, -����.��/���������������

Die eingebettete SQL-Sprache kann im Allgemeinen:

� statisch

� dynamisch

sein.

Wenn eine SQL-Anweisung explizit in einem Datenbankanwendungsprogramm ein-gebettet wird, d.h. wenn die Anweisung zur Übersetzungszeit (bis auf Werte der Host-Variablen) bekannt ist, reden wir von der statischen SQL-Anweisung bzw. statischenSQL-Sprache. Bei der dynamischen SQL-Sprache werden SQL-Anweisungen erst zurLaufzeit dem Programm bekannt gemacht.

��& ���������0���������

SQLJ ist eine eingebettete Sprache, die, im Unterschied zu den anderen entsprechen-den Sprachen (wie ESQL/C++ oder ESQL/Ada) sehr eng in der eigenen Host-Sprache(Java) integriert ist. Diese enge Verbundenheit mit der Host-Sprache zeigt sich beson-ders dadurch, dass Java-Klassen als Datentypen der Tabellenspalten verwendet wer-den können und in der Definition des Iterator-Konzeptes. (Beide Themen werdenspäter in diesem Kapitel ausführlich erörtert.)

Ein wichtiger Vorteil von SQLJ ist, dass es sich um eine standardisierte Sprache handelt.Im Unterschied zu der Standardisierung der SQL-Sprache, wo das ANSI-Gremiumzuerst die Funktionalität festlegt und diese dann von den einzelnen Herstellern imple-mentiert wird, hat bei SQLJ ein Konsortium aus mehreren Datenbankherstellern (Oracle,Compaq/Tandem, JavaSoft, IBM, Informix und Sybase) die Grundlagen der Sprachefestgelegt, die dann vom ANSI-Gremium übernommen wurden. Das Ergebnis ist eineSpezifikation (ANSI-Standard X3.135 »Information technology – Database languages –SQL – Part 10: SQL/OLB), die in drei Teile unterteilt ist: Teil 0, Teil 1 und Teil 2.

Teil 0 beschreibt die Syntax für die statische SQL-Sprache. Er beinhaltet:

� SELECT

� INSERT, UPDATE, DELETE (mit UPDATE WHERE CURRENT OF und DELETEWHERE CURRENT OF)

�������

SQLJ kann nur statisch verwendet werden. (Es ist aber durchaus möglich, durch dieKombination von SQLJ und JDBC dynamisches SQL zu simulieren.)

Page 249: Java in Datenbanksystemen

�� ������� ����!���� ��"

� DDL-Anweisungen (CREATE, DROP und ALTER)

� GRANT und REVOKE.

Teil 1 beschreibt, wie portierbare Java-Prozeduren und benutzerdefinierte Funktionenimplementiert werden können. Teil 2 spezifiziert die Schnittstelle zwischen einemDatenbanksystem und Java, die die Abbildung von Java-Klassen für benutzerdefi-nierte SQL-Datentypen ermöglicht.

Ein wichtiges Ergebnis der Bemühungen der Datenbankhersteller ist die Implementie-rung eines gemeinsamen Translators (Vorübersetzers), mit dem ein einheitlicher Codeauf der SQLJ-Quellebene für alle Datenbanksysteme erstellt werden kann. (DieBeschreibung des Translators siehe später in diesem Kapitel.)

#��!������$%&�'�����(��������#�!����������� ��)�*���++�

Page 250: Java in Datenbanksystemen

�,- ������������� ��

Die SQLJ-Sprache besteht aus einer Menge von Klauseln, die die Java-Sprache erwei-tern. (Eine SQLJ-Klausel ist nichts anders als eine SQL-Anweisung, die in einem SQLJ-Programm nach dem Präfix #sqlj innerhalb der geschweiften Klammern geschriebenwird.) Mit Hilfe von SQLJ kann man Datenbankanwendungen sowohl auf der Client-als auch auf der Server-Seite implementieren. Weil solche Anwendungen in der Java-Sprache geschrieben sind, sind sie portierbar und können mit Datenbanken unter-schiedlicher Hersteller kommunizieren.

Die Phasen, die ein SQLJ-Programm von der Vorübersetzerphase bis zu seiner Ausfüh-rung durchläuft, sehen etwas anders aus, als solche Phasen bei den anderen eingebet-teten SQL-Sprachen. Abbildung 7.1 zeigt dies.

Wie aus Abbildung 7.1 ersichtlich, wird ein SQLJ-Programm mit Hilfe eines Translatorsvorübersetzt. Während der Vorübersetzungsphase werden die eingebetteten SQLJ-Anweisungen durch die Aufrufe zur SQLJ-Laufzeitbibliothek ersetzt. Das Ergebnisdieser Phase ist ein Java-Programm, das von jedem Java-Compiler (oder Interpreter)übersetzt werden kann.

Der übersetzte Java-Bytecode wird von der SQLJ-Laufzeitbibliothek in ein JDBC-Pro-gramm umgewandelt, das schließlich mit Hilfe eines JDBC-Treibers die Aufrufe aufdie entsprechende Datenbank realisiert.

Wie aus dem oben beschriebenen ersichtlich ist, enthält SQLJ zwei Grundkomponen-ten:

� den Translator

� die SQLJ-Laufzeitbibliothek.

Der SQLJ-Translator ist in Java geschrieben, und seine Aufgabe ist, das erstellte SQLJ-Quellprogramm zu übesetzen. (Wie wir schon erwähnt haben, verwenden alle Daten-banksysteme den gleichen Translator.) Das Ergebnis dieser Phase sind eine .java-Dateiund ein oder mehrere SQLJ-Profile (siehe unten), die die Information über die SQL-Operationen enthalten.

Die SQLJ-Laufzeitbibliothek ist genauso wie der Translator in Java geschrieben. IhreAufgabe ist, die Aktionen der im Programm befindlichen SQL-Anweisungen zu imple-mentieren und auf die Datenbank (mit Hilfe von JDBC) zuzugreifen.

Zwei weitere SQLJ-Komponenten sind:

� Customizer

� SQLJ-Profile.

Customizer ist eine Komponente, die automatisch von SQLJ aufgerufen wird, um SQLJ-Profile für die entsprechende Datenbank und herstellerspezifische Funktionen undDatentypen anzupassen. Ein SQLJ-Profil ist eine Sammlung von Eintragungen, in der

Page 251: Java in Datenbanksystemen

�� ������� ����!���� �,%

jede Eintragung genau einer SQL-Operation entspricht. Damit transformiert ein SQLJ-Profil die eingebetteten SQL-Anweisungen in die ausführbaren Anweisungen. Ausdiesem Grund muss jedes Profil mit Hilfe des Customizers angepasst (customized) sein.

Ein SQLJ-Translator generiert ein Profil für jeden Verbindungskontext einer Daten-bankanwendung. (Ein Verbindungskontext kennzeichnet die Umgebung einer Daten-bank, zu der das Programm die Verbindung herstellt.) Die Dateinamen der SQLJ-Profile haben standardmäßig das Suffix .ser, können aber optional in die .class-Dateienumgewandelt werden.

Eine wichtige Eigenschaft der SQLJ-Profile ist, dass sie portierbar sind. Das heißt, dassein Profil aus einer herstellerspezifischen Umgebung (z.B. Oracle auf Windows NT) zueiner anderen (z.B. DB2 auf OS/390) übertragen werden und nach dem durchgeführtenAnpassungsprozess einwandfrei in der neuen Umgebung verwendet werden kann.

��&�� )(�������1(������/�)���������#���-2+

Der wichtigste Unterschied zwischen den beiden Sprachen ist, dass SQLJ eine statischeund JDBC eine dynamische Sprache ist. (Eine Sprache wird dynamisch genannt, fallsder Datenbankprogrammierer mit ihr Datenbankobjekte abfragen und ändern kann,die erst zur Ablaufzeit bekannt sind. Das gilt nicht nur für Datenbankobjekte, sondernauch für ganze SQL-Anweisungen.)

Im Unterschied zu JDBC, kann SQLJ nur statisch verwendet werden, d.h. alle SQL-Anweisungen und alle in ihnen verwendeten Datenbankobjekte (bis eventuell auf dieWerte der Host-Variablen) sind zur Übersetzungszeit bekannt.

Obwohl eine dynamische Sprache flexibler als eine statische ist, hat SQLJ mehrere Vor-teile im Vergleich zu JDBC. Diese sind:

� SQLJ befindet sich auf einem höherem logischen Niveau als JDBC

� SQLJ hat eine einfachere Syntax als JDBC

� SQLJ kann die Syntax- und Semantikanalyse zur Übersetzungszeit durchführen.

Im Unterschied zu JDBC, wo alle SQL-Anweisungen, die in einem JDBC-Programm inMethodenaufrufen versteckt sind, ist jede SQL-Anweisung in einem SQLJ-Programmin ihrer ursprünglichen Form dargestellt und dadurch gleich sichtbar. Aus diesemGrund kann man SQLJ als logisch höhere Programmiersprache (als JDBC) bezeichnen.

Um die einfachere SQLJ-Syntax zu zeigen, werden wir ein Beispiel benutzen.

Beispiel 7.1

(�����) �� ���**�+��*����,�������&��� �� ��**�+��*�-�����.��� ����/012��+��34�0���+�,56�!�����*�* ��7�8��+��!

Page 252: Java in Datenbanksystemen

�,� ������������� ��

(�����0���*��*��+���,�����9���*���� :��!�+�����9*��!���,��+���7�*�* ��7�8�!�+����&����!

������&���������.��� ����;#.1�<�� �/012��+��34�0���+�,�<�+��!

Der erste Teil des Beispiels 7.1 zeigt einen Ausschnitt aus einem JDBC-Programm, indem eine SELECT-Anweisung mit Hilfe der prepareStatement()-Methode vorbereitetwird und danach die Spaltenwerte den entsprechenden Variablen zugewiesen werden.Um dieselbe Funktionalität mit Hilfe von SQLJ zu implementieren, reicht eine einzigeProgrammzeile, wie aus dem zweiten Teil des Beispiels ersichtlich ist.

SQLJ kann die Syntax- und Semantikanalyse zur Übersetzungszeit durchführen, weilzum Zeitpunkt der Übersetzung die Verbindung zur entsprechenden Datenbankbekannt ist. Jede SQLJ-Klausel steht im Zusammenhang mit einer Datenbankverbin-dung, welche die Umgebung dieser Anweisung eindeutig definiert. Aus diesemGrund ist es möglich, die Kompatibilität von Java und SQL-Ausdrücken zur Überset-zungszeit zu überprüfen.

Im Unterschied zu SQLJ werden in einer JDBC-Umgebung die SQL-Anweisungennicht zur Übersetzungszeit überprüft, wodurch syntaktische Fehler erst zur Laufzeiterkannt werden.

��&�& ���$�%��������

Alle SQLJ-Anweisungen können in zwei Gruppen unterteilt werden:

� Vereinbarungsanweisungen (declaration statements)

� Ausführungsanweisungen (executable statements).

Vereinbarungsanweisungen werden in SQLJ entweder für die Erstellung von Iterator-Klassen oder für Verbindungskontexte verwendet. (Beide Begriffe werden spätererläutert.)

Beispiel 7.2 zeigt eine Vereinbarungsanweisung.

Beispiel 7.2

==�;*� *& ���> �� ��������'����*� *& ��*� 8���* ��7���* ��7���&�'��!

In Beispiel 7.2 wird mit Hilfe einer Vereinbarungsanweisung der Iterator iter1 dekla-riert.

�������

Jede SQLJ-Anweisung hat am Anfang das Präfix #sql.

Page 253: Java in Datenbanksystemen

�� ������� ����!���� �,.

Ausführungsanweisungen werden benutzt, um eingebettete SQL-Anweisungen aus-zuführen. Im Unterschied zu den Vereinbarungsanweisungen werden Ausführungs-anweisungen innerhalb der geschweiften Klammer geschrieben.

In Beispiel 7.3 wird eine Ausführungsanweisung gezeigt.

Beispiel 7.3

����������.��+���+�*?�;#.1�<�+��<�+�*?�/012�>������34�0��>������ �,�<>������ ��!

Beispiel 7.3 zeigt eine SELECT INTO-Anweisung, die unter anderem drei Host-Varia-blen (name, umsatz und kundennr) enthält. (Eine SELECT INTO-Anweisung stellteine erweiterte Form der SELECT-Anweisung dar, die speziell in der eingebettetenSQL-Sprache verwendet wird, um Spaltenwerte der aktuellen Reihe den Host-Varia-blen zuzuweisen.

Mit dem Begriff SQLJ-Klausel wird der Teil einer Ausführungsanweisung bezeichnet,der sich rechts von dem Präfix »#sql« und innerhalb der geschweiften Klammernbefindet.

Eine SQLJ-Klausel kann:

� eine Zuweisungsklausel (assignment clause)

� eine Anweisungsklausel (statement clause)

sein. Eine Zuweisungsklausel enthält einen oder mehrere Ausgabewerte. Damit stelltdie Klausel mit der SELECT INTO-Anweisung in Beispiel 7.3 eine Zuweisungsklauseldar. Wie aus Beispiel 7.3 ersichtlich, erlaubt SQLJ die Zuweisung ausgewählter Wertedirekt zu Host-Variablen innerhalb einer SQL-Anweisung. Die einzige Einschränkungbei solcher Zuweisung ist, dass die Abfrage eine einzige Reihe als Ergebnismenge lie-fert. (Beispiel 7.5 zeigt ein SQLJ-Programm, in dem die SELECT INTO-Anweisung ver-wendet wurde.) Eine Anweisungsklausel enthält keinen Ergebnisausdruck und liefertdamit keine Ausgabewerte. Jede DDL-Anweisung sowie alle DML-Anweisungen(außer SELECT) sind Beispiele für Anweisungsklauseln.

Beispiel 7.4 zeigt eine Anweisungsklausel.

Beispiel 7.4

;#��0.�;#.1�+�* '��*� �@��A���<� �<�+��<�& �+���<'*� �

��&�* ���'(���$����!�3�

SQLJ-Host-Ausdrücke dienen dem Datenaustausch zwischen dem Anwendungspro-gramm (geschrieben in SQLJ) und der Datenbank. Diese Ausdrücke befinden sich ineingebetteten SQL-Anweisungen und sind nichts anderes als gewöhnliche Java-Aus-

Page 254: Java in Datenbanksystemen

�,� ������������� ��

drücke. Generell kann man sagen, dass jeder gültige Java-Ausdruck als Host-Ausdruckverwendet werden kann. Damit sind Felder, Klasseninstanzen, Methodenaufrufe undarithmetische Ausdrücke Beispiele für mögliche Host-Ausdrücke.

Die generelle Syntax für einen Host-Ausdruck ist:

<B+&���C���&�*D��� ��>��'?��

<B+&���C��&�*D� �

Damit muss ein Host-Ausdruck, im Unterschied zu einer Host-Variablen, immer inKlammern geschrieben werden.

Die optionale modus-Angabe kennzeichnet den Modus eines Host-Ausdrucks. DerModus eines Host-Ausdrucks kann IN, OUT oder INOUT sein. IN spezifiziert, dassder Wert des Host-Ausdrucks von der SQL-Anweisung, die ihn beinhaltet, gelesenwird. Demgegenüber spezifiziert OUT, dass der Wert des Host-Ausdrucks geändertwird durch die SQL-Anweisung, die ihn enthält.

Diese beiden Angaben müssen oft nicht explizit angegeben werden, weil sie als solchevom SQLJ-System impliziert werden. Bei der SELECT INTO-, sowie FETCH-Anwei-sung haben die verwendeten Host-Ausdrücke standardmäßig die Angabe OUT, wäh-rend in fast allen anderen Fällen die standardmäßige Angabe für einen Host-AusdruckIN ist.

Die INOUT-Angabe spezifiziert, dass der Wert des Host-Ausdrucks sowohl lesend alsauch schreibend verwendet wird. Diese Angabe muss vor einem Host-Ausdruck expli-zit angegeben werden.

Als weiteres Beispiel soll hier noch die Syntax des SET-Statements angegeben werden:

��������.�<�&�*D� �,���� ��>��!

Diese Anweisung dient zur Berechnung eines Ausdrucks und der Zuweisung diesesAusdrucks an eine Host-Variable.

�������

Die einfachste Form eines Host-Ausdrucks bildet eine Host-Variable, die einen ein-fachen Java-Identifikator darstellt.

�������

Es ist bei der Verwendung von Host-Variablen immer auf die korrekte Typkonver-tierung zwischen den SQL-Datentypen und den entsprechenden Java-Datentypenzu achten. Die Tabellen mit der Konvertierung entsprechender Typen sind in derEntwicklerdokumentation jedes Datenbanksystems zu finden.

Page 255: Java in Datenbanksystemen

�� ������� ����!���� �,,

��&�, 4����������������������

Die Fehlerbehandlung für SQLJ basiert auf den Ausnahmen der Sprache Java, d.h. aufden Ausnahmen der Klasse SQLException. (Diese Klasse ist eine Unterklasse derKlasse Exception.) Die Information, die die SQLException-Klasse liefert, enthält Feh-lermeldungstext, verschiedene Fehler-Codes und eine Kette von Ausnahmen.

Der Fehlermeldungstext beschreibt den aufgetretenen Fehler. Eine Anwendung, dieden Fehlermeldungstext benutzt, greift auf diesen String-Wert mit Hilfe der getMes-sage()-Methode zu. Der Fehler-Code kann entweder herstellerspezifisch sein oder demXOPEN-Standard entsprechen. Dementsprechend existieren zwei unterschiedlicheMethoden der Klasse SQLException, die beide einen ganzzahligen Fehler-Code alsRückgabewert liefern.

Weitere Informationen über die SQLException-Klasse befinden sich in Kapitel 4.

��&�5 6������#��������$�� !���������������7�(���//�

In diesem Abschnitt werden wir die manuelle Übersetzung und Ausführung einesSQLJ-Anwendungsprogramms zeigen. (Bei dem Programm handelt sich um eine sogenannte Client-Anwendung, d.h. um ein Programm, das sich auf der Client-Seite desSystems befindet.)

SQLJ verwendet grundsätzlich einen Translator, mit dem die Quellprogramme in Javaübersetzt werden. Um den Translator zu starten, muss das sqlj-Kommando ausgeführtwerden. Dieses Kommando hat folgende Syntax:

��(�B&�*�&���C��*�����

wobei datei das Präfix .sqlj enthält und optionen eine Liste von Optionen darstellt.(Eine Auswahl der möglichen Optionen ist in Tabelle 7.1 gegeben.)

�������

Wir nehmen an, dass die CLASSPATH-Umgebungsvariable gesetzt ist. Diese Varia-ble legt fest, wo die .class-Dateien gespeichert sind. Für die ausführliche Beschrei-bung der CLASSPATH-Umgebungsvariablen siehe Kapitel 3.

������ ������ ���

���� 8��������������������9���(����/���2������������

�(/���� $3��1������#%�����3��1���������6������#������������������1��-�������

�(/�������:�������� ;�/��������� !��������-�����������1��6������#����

/���!!���$%&�0�*���������<�=�1*++���*�

Page 256: Java in Datenbanksystemen

�,� ������������� ��

Die in Beispiel 7.5 dargestellte Batch-Datei wurde von uns benutzt, um Oracle-SQLJ-Programme in diesem und den nächsten beiden Kapiteln zu übersetzen.

Beispiel 7.5

E���&�&FF0�2�) +�*� ���*�� �������G��� ���H*��� +�*� <�I#+�J�I�����7J��.�10�$;0,$<K) &7 ++�K1 ����.��$L,$<K(�>8�MK'����.�310L$;0,F<K(�'D'�����.�����)�.4,N310L$;0N!N10�$;0NK��(K�'K ��*�+�8O�?��!N10�$;0NK��(K�'K* ��*& �?��!�!N10�$;0NK(�'�K�'K�����8O�?��!���&�P'� ��*?������0�2�����%$*���Q��������+�*�����*����@� ����������*��@� ��&����7�FR� *��� ����&��Q�����*������%$*�����N8����0�2�$�����S����FR �1��������>��7<

���&����� $3��1������#%�����3��1���������>/���#����1(�����������������7�( ��������"�������

���������-����3�������/������1(����� !�����������-���������������//����2�(%������� (��������������?�����������"��������@A�

������ $3��1������#%�����3��1����������( (��������������#������������)������������

����/�� $3��1������#%�����3��1���������)��%�������1(��"��������������/���8�������/�

/�������������������������

�(/������(������ ��� ;�/������-����B������������$�������������1��+(/�������������������%�����

��� ����������������������B�%��������$��������� ���������%������

��( ��� $3��1������#%�����3��1���������7�( ������������

���(���� 0��������)������!��������1(������������������?����������9���(������������������B�%��������-����1������!����������/��.���//��3/���C �������(����D�

����(//���A

� -������//1��#�������B������/���������������������������-��������� �������

-�����9���(��%������������������1��6������#���!���������

���1�� -�����������=��������-2+��������B����������������������

��� -���2����1��#�������� !��������������������1��-�������

�������

Die Verwendung der Option linemap ist empfehlenswert, weil sie den Hinweis aufdie Zeilennummern der SQLJ-Dateien liefert. Dieser Hinweis kann im Falle einesFehlers nützlicher sein als der standardmäßige Verweis auf die Zeile des übersetz-ten Java-Programms.

������ ������ ���

/���!!���$%&�0�*���������<�=�1*++���*��23*���(���4

Page 257: Java in Datenbanksystemen

�� ������� ����!���� �,�

0�2�N10�$;0NK'��K��(��9��%��� ,��&**�%����& �,*�7� �%�� O����%�&+���,F���%�9����N8NO0�2�$�����S����FR �>����1��������>��7��F��) &7 ++�� �*�����$*��������R'� � RF*��� ��������* G7*�N10�$;0NK'��K��(��9��%�� O����%�&+���,F���%�9����N8NO���&�L&+���� �N�$LNK(���N8�(����&�/� *�7

Die in Beispiel 7.5 verwendete Batch-Datei ist generell, d.h. mit kleineren Änderungenauch für andere Datenbanksysteme anwendbar. Zuerst wird eine Variable ORADIRdeklariert, welche das Installationsverzeichnis zur Datenbank erhält. Damit kann diemehrfache Angabe im CLASSPATH eingespart werden. Der Klassenpfad zeigt auf alledatenbankspezifischen Archivdateien: Im vorliegenden Beispiel auf ein Archiv für dieLaufzeitklassen und auf ein anderes für den Vorübersetzer. (Bei vielen Datenbank-systemen wird für den Vorübersetzer bzw. für SQLJ ein eigenes Archiv verwendet.)

Manche Vorübersetzer erlauben die automatische Übersetzung der Klassendateien. ImZusammenhang mit speziellen Editoren empfiehlt es sich jedoch, diese Option zudeaktivieren und explizit den Übersetzungsvorgang zu starten.

��&�E ���������������$�%���������(������������/����

Eingebettete SQL-Anweisungen ohne Ergebnismenge sind u.a.

� alle Datendefinitionsanweisungen

� UPDATE und DELETE ohne CURRENT OF-Klausel (die CURRENT OF-Klauselwird in einem späteren Abschnitt beschrieben)

� die INSERT-Anweisung.

Das folgende Beispiel stellt ein SQLJ-Programm dar, in dem eine Tabelle erstellt wird.Das Beispiel zeigt die prinzipielle Anwendung von SQLJ in einem Java-Programm.

�������

Es ist darauf zu achten, dass nur die Archive eines Datenbanksystems im Klassen-pfad vorhanden sind. Sonst kann es vorkommen, dass der falsche Vorübersetzerverwendet wird oder nicht nachvollziehbare Fehlermeldungen entstehen. Je nachAnwendungsfall sollte die Online-Überprüfung der SQL-Anweisungen aktiviertoder deaktiviert werden. (Die Optionen user, password und url des sqlj-Komman-dos aktivieren diese Überprüfung.) Falls sich SQL-Anweisungen auf noch nichtvorhandene Datenbankobjekte beziehen, wird bei einer Online-Überprüfung eineFehlermeldung vom System ausgegeben. (Trotzdem sollte diese Überprüfung,wenn möglich, aktiviert sein.)

Page 258: Java in Datenbanksystemen

�,� ������������� ��

Beispiel 7.6

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!�+�& *���(� ��*�+�� �F�$�F�*�&�*�9*!��'�������$2�������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :�����������������������������$�F�*�&�*�9*���*$�F�*�&�*�9*����$�F�*�&�*�9*��&���!���������������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK�.'��� �*������ �!��������������������==$���*�� �����+�FR �$HO��G������������������������F��$H2��,,�$HA*���$HO���������.��A00�#.���4�2��$HO�$2;#��!��������������������==�**���������%$2�%��������7�+�*��������FR� ����������������������������0��.��.�H���*'��8���&�+�8��� �V���&*�����&�+�O��� �OW���&*������&�+�M��� �8X������������������������!���������������������:�*�+�&�*�� ��*�� .'���*'��8�� �*�* �!���������������������������������������������������$01)�.�H���*'��8���������������������!���������������������:�*�+�&�*�� ��*�� .'���*'��8�7�Q���* �!��������������������==�'������ '��*��TTTTTTTTTTTTTTTTTTT���������������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&�����

DB2, INFORMIX, ORACLE, MySQL

Page 259: Java in Datenbanksystemen

�� ������� ����!���� �,"

�������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.6 sieht folgendermaßen aus:

@� '�����7�?��$H�1L.'���� �*������.'���*'��8�� �*�*.'���*'��8�7�Q���*

Beispiel 7.6 verwendet die CREATE TABLE-Anweisung, um eine neue Tabelle(tabelle1) zu erstellen. (Die Tabelle wird anschließend mit der DROP TABLE-Anwei-sung gelöscht.) Dieses Beispiel verwendet, genauso wie alle vorherigen JDBC-Pro-gramme, das Dienstprogramm namens DBUtils, um die entsprechende Umgebung(Oracle, MySQL, Informix oder IBM DB2) festzulegen. Für die Beschreibung diesesDienstprogramms siehe Kapitel 4.

��&�� -�����������������������+��$�%�������(����������(�

Eine SELECT-Anweisung kann eine oder mehrere Reihen als Ergebnismenge liefern.(Der Fall, wo eine Abfrage keine Reihen liefert, wird bei den eingebetteten Sprachengenauso behandelt wie wenn eine einzige Reihe als Ergebnis existiert.) Falls eineAbfrage eine einzige Reihe liefert, gibt es keine Notwendigkeit für eine Überbrückungzwischen einer mengenorientierten Sprache wie SQL und einer satzorientierten Spra-che wie Java, weil jede satzorientierte Sprache eine einzige Reihe problemlos bearbei-ten kann.

Beispiel 7.7 zeigt ein SQLJ-Programm, das u.a. eine Abfrage auf die Tabelle mitarbeiterausführt. (Dieses Programm kann nicht mit MySQL verwendet werden, weil diesesDatenbanksystem zur Zeit keine Transaktionen unterstützt.)

Beispiel 7.7

Ändern Sie die Aufgabe jenes Mitarbeiters, dessen Personal- und Projektnummer amBildschirm eingegeben werden. Zusätzlich soll die Anzahl der Reihen in der Tabellemitarbeiter ausgegeben werden sowie die durchgeführte Änderung mit Hilfe der Roll-back-Funktion rückgängig gemacht werden.

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!

DB2, INFORMIX, ORACLE

Page 260: Java in Datenbanksystemen

��- ������������� ��

�+�& *���(� ��*�+�� �F�$�F�*�&�*�9*!��'���������A��0&'�>�����**���F�����*�$H2��,�$HA*���;#/102;�!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!�����**����**�+��*��*+*�,���!�����**���0���*��*� ��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������==�FR �0&'�>���*&�&++�*�'���*��<�������������&����*��*&�&++�*�F���!������������$�F�*�&�*�9*���*$�F�*�&�*�9*����$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!������������==$���*�� �����+��G����Y�FR �$HO�� F& �� ���UUU�������������F��$H2��,,�$HA*���$HO����������.��A00�#.���4�2�$HO�$2;#��!������������==�0������?�����.'���2�* '��*� �����<�������������* ��7�+D� �� D� ��F7'�!������������&�7��&��*8!�������������:�*�+�&�*�� ��*�� K���?���� �0���������.'��2�* '��*� ��&����� �!��������������������������������������.��&��*�T����*&�<�&��*8�F &+�+�* '��*� �������������!�������������:�*�+�&�*�� ��*��� 0���������2�* '��*� <� �"�&��*8��!������������==�$*��'�>%A��*�<�������������:�*�+�&�*�� ��*�� K�K�Z�'�����������#�++� ����2�* '��*� ���<� �!������������+D� �,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ��������!�������������:�*�+�&�*�� ��*�� K�Z�'�����������) &(�>*��++� ��< �!������������� D� �,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ��������!������������* :����������������������������������������������.��F7'����*&�<�F7'��F &+� '��*������ �+D� �,�<+D� ����� D� �,�<� D� �����������������!�����������������:�*�+�&�*�� ��*�� $� �2�* '��*� �+�*��� )� �&���++� � "+D� " ���*� "�F7'�" ��+�) &(�>*� "� D� �!�����������������:�*�+�&�*�� ��*�� K�Z�'������������������F7'�����2�* '��*� ���<� �!�����������������F7'��,�����H�FF� ��0��� ����

Page 261: Java in Datenbanksystemen

�� ������� ����!���� ��%

;���*�* �+0��� ��:�*�+������ ��������!����������������������������������������A)$�.�� '��*�����*��F7'��,�<�F7'����� �+D� ,�<+D� ����� D� ,�<� D� �����������������!����������������==A��*�%0&'�><�����������������:�*�+�&�*�� ��*�� K�K�0&'�>��������*����� �!����������������������01��H��L�310L��!�����������������:�*�+�&�*�� ��*�� 0&'�>�F� *�7� �!��������������*�������9���*�&���&*F&����������������������:�*�+�&�*�� ��*�� 2�* '��*� �����*��& �����U �!�������������������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.7 ist:

@� '�����7�?��$H�1L��?���� �0���������.'���2�* '��*� ��&�����0���������2�* '��*� <�[Z�'�����������#�++� �����2�* '��*� ���<8W8WOZ�'�����������) &(�>*��++� ��<�8$� �2�* '��*� �+�*��� �)� �&���++� �8W8WO���*�) &(�>*��*� ��+�) &(�>*��8Z�'������������������F7'������2�* '��*� ���<Z �������*� 0&'�>��������*�����0&'�>�F� *�7�

In Beispiel 7.7 wird zuerst mit Hilfe einer SELECT INTO-Anweisung die gesamteAnzahl der Reihen der Tabelle mitarbeiter in die LONG-Variable namens count1gespeichert. Danach wird (mit einer ähnlichen SELECT INTO-Anweisung) eine ein-zige Reihe der Tabelle arbeiten ausgewählt. (Den Primärschlüssel der Tabelle arbeitenstellt die Kombination der Spalten m_nr und pr_nr dar. Aus diesem Grund wird fürjede Angabe der beiden Werte höchstens eine Reihe geliefert.)

Page 262: Java in Datenbanksystemen

��� ������������� ��

Mit der nachfolgenden UPDATE-Anweisung wird die Aufgabe des Mitarbeiters durcheinen vom Benutzer angegebenen Wert geändert. Abschließend setzt die ROLLBACK-Anweisung diese Änderung zurück.

��&�F -���������������������+��$�%�������/���������(�

Falls eine Abfrage mehrere Reihen als Ergebnismenge liefert, kann diese innerhalbeines Java-Programms nicht direkt abgearbeitet werden, weil die Java-Sprache(genauso wie alle anderen prozeduralen Sprachen) satzorientiert ist, d.h. zu einemZeitpunkt nur einen einzelnen Satz abarbeiten kann. Aus diesem Grund besteht dieNotwendigkeit, die Ergebnismenge einer SQL-Abfrage der Java-Sprache reihenweisezu übergeben, damit diese jede einzelne Reihe problemlos bearbeiten kann. Für solcheFälle unterstützt SQLJ Iteratoren.

Iteratoren entsprechen den Cursorn, die am Anfang dieses Kapitels erörtert wurden,zeigen aber zu ihnen signifikante Unterschiede. (In Bezug auf JDBC ist ein Iterator inseiner Wirkungsweise mit einer Instanz der 0���*��*-Klasse vergleichbar.)

Der wichtigste Unterschied zwischen einem Cursor und einem Iterator ist, dass ein Ite-rator direkt zur Java-Sprache gehört, weil es sich um eine Klasse handelt. (Solche Kon-strukte, die direkt zu einer Sprache gehören, werden first class objects genannt.) Ausdiesem Grund kann ein Iterator als Parameter einer Methode übergeben werden.Genauso kann er außerhalb der SQLJ-Übersetzungseinheit, die ihn deklariert hat, ver-wendet werden, ohne seine statischen Eigenschaften zu verlieren. Demgegenüber istein Cursor kein first class object der jeweiligen Hostsprache, weil es sich um ein spezifi-sches SQL-Konstrukt handelt, das benutzt wird, um den Unterschied zwischen einermengenorientierten Sprache (SQL) und einer satzorientierten Sprache (wie C, C++) zuüberbrücken.

SQLJ unterstützt zwei Iterator-Typen:

� benannte Iteratoren

� positionierte Iteratoren.

Die beiden Iterator-Arten werden in den nachfolgenden Abschnitten beschrieben.

5�������6���*���

Ein SQLJ-Programm, das einen benannten Iterator verwendet, beinhaltet immer fol-gende Schritte:

1. die Definition einer Iterator-Klasse mit Hilfe einer SQLJ-Deklaration

2. die Deklaration einer Iterator-Instanz

Page 263: Java in Datenbanksystemen

�� ������� ����!���� ��.

3. die Erstellung der Verbindung zwischen der Ergebnismenge einer Abfrage und derIterator-Instanz

4. den Zugriff auf die aktuelle Reihe der Ergebnismenge mit Hilfe der next()-Methode

5. das Lesen der Spaltenwerte der aktuellen Reihe

6. das Schließen der Iterator-Instanz mit Hilfe der close()-Methode.

Folgendes Beispiel zeigt die Verwendung eines benannten Iterators.

Beispiel 7.8

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!==��������� �& ���> �� ���+�*�4�F��������;*� *& �<==�#+���H�����7�����*� *& ��� �& 8���* ��7�+D� ��* ��7�+D�+����* ��7�+D�& �+��!��'�������#+�;*� ������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������$�F�*�&�*�9*���*$�F�*�&�*�9*����$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!������������==�$���*�� �����+��G����Y�FR �$HO�� F& �� ���UUU�������������F�$H2�,,$HA*���$HO��������.��A00�#.���4�2��$HO�$2;#��!�������������� �& 8��� �& 8!�==��� �& ���> �� ���������������* ��7��* 8�,���!�������������* ��7�+9!�==�1'� 7 ��?��������������:�*�+�&�*�� ��*�� K�K�Z�'����������'���?������� +D� �������7�'���+Q��*��<� �!������������+9�,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ��������!������������==�#+����&�+�%H�����7<������������������ �& 8�,�����������������������.�+D� ��+D�+���+D�& �+��F &+�+�* '��*�

DB2, INFORMIX, ORACLE, MySQL

Page 264: Java in Datenbanksystemen

��� ������������� ��

��� ��+D� �I�<+9�& �� �':�+D� �������������!�������������:�*�+�&�*�� ��*�� 2�* '��*� �+�*�+D� �I� "+9" <� �!�������������������� �& 8���9*����������������������* 8�,��� �& 8�+D� ��!�����������������:�*�+�&�*�� ��*�� �+D� ,� �"��* 8�!�����������������* 8�,��� �& 8�+D�+���!�����������������:�*�+�&�*�� ��*�� �+D�+�,� �"��* 8�!�����������������* 8�,��� �& 8�+D�& �+���!�����������������:�*�+�&�*�� ��*��� �+D�& �+�,� �"��* 8�!��������������������������� �& 8��&����!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.8 ist:

@� '�����7�?��$H�1LZ�'����������'���?������� �+D� �������7�'���+Q��*��<OWWWW2�* '��*� �+�*�+D� �I�OWWWW<+D� ,�8W8WO�+D�+�,�4�'� �����������������+D�& �+�,�)�* +D� ,�8\M8]�+D�+�,�2R� �����������������+D�& �+�,�Z' ���+D� ,�^WM8�+D�+�,�2��� �����������������+D�& �+�,�0��� +D� ,�OX\8�+D�+�,�L�F+����������������+D�& �+�,�H �7�**�

In Beispiel 7.8 wird mit Hilfe der folgenden SQLJ-Vereinbarungsanweisung

�����*� *& ��� �& 8���* ��7�+D� ��* ��7�+D�+���* ��7�+D�& �+��!

der benannte Iterator namens Cursor1 deklariert. Auf der Basis dieser Anweisungwird eine Java-Klasse von SQLJ erstellt. Das heißt, dass der SQLJ-Translator die Itera-tor-Deklaration durch die Deklaration einer Java-Klasse mit dem gleichen Namenersetzt. Falls der Iterator innerhalb der Klasse deklariert werden soll, muss er innerhalbdie Angaben public und static enthalten.

Page 265: Java in Datenbanksystemen

�� ������� ����!���� ��,

Der Iterator Cursor1 enthält drei Attribute: m_nr, m_name und m_vorname. Aus die-sem Grund kann Cursor1 mit jeder Abfrage in Verbindung gebracht werden, die inihrer SELECT-Liste diese drei Spalten (oder eine Untermenge davon) enthält. In Ver-bindung mit einem Funktionsaufruf innerhalb der SELECT-Anweisung muss für eineeindeutige Identifizierung des Spaltennamens und damit der Cursor-Zugriffsmethodeein Aliasname angegeben werden.

Die gleichnamige Java-Klasse Cursor1 wird nach der Erstellung Folgendes enthalten:

� eine next()-Methode, die Daten satzweise bearbeitet

� Zugriffsmethoden m_nr(), m_name() und m_vorname(), die die Werte der entspre-chenden Spalten der aktuellen Reihe zurückgeben

� die Methode close(), die die Iterator-Instanz deaktiviert.

Im nächsten Schritt – die Deklaration einer Iterator-Instanz – wird ein Objekt dekla-riert, das im Zusammenhang mit der Ergebnismenge der entsprechenden SELECT-Anweisung steht. Die Anweisung

�� �& 8��� �& 8!

deklariert die Iterator-Instanz cursor1. In diesem Zusammenhang ist es wichtig zu wis-sen, dass jede Deklaration einer Iterator-Instanz eine Java- und nicht eine SQLJ-Dekla-ration ist. (Das ist ein signifikanter Unterschied zu den anderen eingebetteten SQL-Schnittstellen, wo der Cursor ein SQL-Objekt darstellt.) Damit handelt es sich bei einerIterator-Instanz um ein Java-Objekt, das genauso verwendet werden kann wie jedesandere Objekt der Java-Sprache.

Die Anweisung

������ �& 8�,�������.�+D� ��+D�+���+D�& �+��F &+�+�* '��*� ���� ��+D� �I�<+9�& �� �':�+D� ��!

verbindet die Iterator-Instanz mit der Ergebnismenge der Abfrage. Die Namen undDatentypen der Spalten, die in der SELECT-Liste angegeben sind, müssen den Namenund Datentypen der entsprechenden Attribute in der Deklaration eines benannten Ite-rators entsprechen. (Die Reihenfolge der Spalten in der SELECT-Liste ist nicht rele-vant.)

�������

Die Anzahl der Spalten in der SELECT-Liste muss nicht mit der Anzahl der Attri-bute in der Iterator-Deklaration übereinstimmen. Einige Attribute in der Iterator-Deklaration können durchaus keine entsprechenden Spalten in der SELECT-Listehaben, d.h. die Anzahl der Spalten muss kleinergleich als die Anzahl der Attributein der Iterator-Deklaration sein.

Page 266: Java in Datenbanksystemen

��� ������������� ��

Wie aus der obigen Anweisung ersichtlich, handelt es sich bei der SQLJ-Anweisungum eine Zuweisungsklausel, weil das Ergebnis der SELECT-Anweisung einer Iterator-Instanz zugewiesen wird.

In der while-Schleife:

��������� �& 8���9*����������

wird die next()-Methode verwendet, um die nächste Reihe der Ergebnismenge zuholen. Mit Hilfe der schon erwähnten Zugriffsmethoden der Java-Klasse (m_nr(),m_name() und m_vorname()) werden die Spaltenwerte der aktuellen Reihe geholt. DieMethode next() gibt den Booleschen Wert false zurück, falls keine weitere Reihe derErgebnismenge zum Lesen vorhanden ist.

Schließlich wird die Iterator-Instanz mit der Anweisung

�� �& 8��&����!

deaktiviert.

)*�*������6���*�

Beispiel 7.9 zeigt ein SQLJ-Programm mit einem positioniertem Iterator.

Beispiel 7.9

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!==��������� �& ���> �� ���+�*�4�F��������;*� *& �<==�)&��*�&��H�����7�����*� *& ��� �& 8���* ��7����* ��7����* ��7���!

�������

Falls mit einer SELECT-Anweisung NULL-Werte für eine gewisse Spalte geliefertwerden können, ist es empfehlenswert, das zur Spalte korrespondierende Attributmit Hilfe der Java-Klasse Integer zu definieren. In diesem Fall werden alle NULL-Werte als solche ausgegeben. Falls die Spalte mit Hilfe des primitiven Datentyps intdeklariert wird, wird vom System jedes Mal eine Ausnahme namens SQLNullEx-ception geliefert, wenn der NULL-Wert ausgegeben wird. (Die Integer-Klasseumfasst den primitiven Typ int.)

DB2, INFORMIX, ORACLE, MySQL

Page 267: Java in Datenbanksystemen

�� ������� ����!���� ���

��'�������)&�;*� ������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :��������������$�F�*�&�*�9*���*$�F�*�&�*�9*����$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!������������==$���*�� �����+�FR �$HO��G����������������F��$H2��,,�$HA*���$HO����������.��A00�#.���4�2��$HO�$2;#��!�������������� �& 8��� �& 8!�������������* ��7��* 8�,���!�������������* ��7�+9!�==1'� 7 ��?��������������:�*�+�&�*�� ��*�� K�K�Z�'����������'���?������� +D� �������7�'���+Q��*��<� �!������������+9�,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ��������!������������==)&��*�&���&�+�%H�����7<������������������ �& 8�,�����������������������.�+D� ��+D�+���+D�& �+��F &+�+�* '��*� ��� ��+D� �I�<+9�& �� �':�+D� �������������!�������������* ��7�,���',����,��!��������������������������������/�.�4�<�� �& 8�;#.1�<��<'��<��������������!������������������U�� �& 8����/�*�����������������������:�*�+�&�*�� ��*�� �+D� ,� "" �+D�+�,� "'" +D�& �+�,� "��!����������������������������������������/�.�4�<�� �& 8�;#.1�<��<'��<������������������!��������������������������� �& 8��&����!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&�����

Page 268: Java in Datenbanksystemen

��� ������������� ��

�������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.9 ist:

@� '�����7�?��$H�1LZ�'����������'���?������� �+D� �������7�'���+Q��*��<8XWWW2�* '��*� �+�*�+D� �I�8XWWW<+D� ,�8W8WO�+D�+�,�4�'� ����������������+D�& �+�,�)�* +D� ,�^WM8�+D�+�,�2��� �����������������+D�& �+�,�0��� +D� ,�OX\8�+D�+�,�L�F+����������������+D�& �+�,�H �7�**�

Obwohl die Beispiele 7.8 und 7.9 identisch sind (in Bezug auf das Problem, das sieimplementieren), existieren zwischen ihnen signifikante Unterschiede, weil das ersteeinen benannten und das zweite einen positionierten Iterator verwendet. FolgendeListe enthält die wichtigsten Unterschiede:

� die Deklaration der Iterator-Klasse ist verschieden.

� die Reihen der Ergebnismenge bei einem positionierten Iterator werden mit Hilfeder SQLJ-Anweisung namens FETCH geholt.

� das Endkriterium in Bezug auf die Ergebnismenge wird mit Hilfe der endFetch()-Methode getestet.

Die Deklaration der Iterator-Klasse bei einem positionierten Iterator beinhaltet nur dieDatentypen der Attribute:

�����*� *& ��� �& 8���* ��7����* ��7����* ��7���!

Der Grund dafür ist, dass die Übereinstimmung zwischen den Attributen und den ent-sprechenden Spalten nicht mit Hilfe von Namen, sondern ausschließlich mit Hilfeihrer Position ermittelt wird.

Die einzelnen Reihen der Ergebnismenge werden bei einem positionierten Iterator mitHilfe der SQL-Anweisung FETCH geholt (und nicht wie bei einem benannten Iteratormit der Java-Methode next()):

�����/�.�4�<�� �& 8�;#.1�<��<'��<��!

Damit hat ein SQLJ-Programm, das einen positionierten Iterator verwendet, mehrÄhnlichkeiten mit der Einbettung von SQL in Sprachen wie C und C++, weil diese diegleichnamige SQL-Anweisung (FETCH) für das Holen einzelner Reihen benutzen.

Page 269: Java in Datenbanksystemen

�� ������� ����!���� ��"

Eine Konsequenz der Verwendung der FETCH-Anweisung ist, dass bei einem positio-nierten Iterator keine Zugriffsmethoden wie bei einem benannten Iterator existieren.Diese sind auch nicht notwendig, weil die Spaltenwerte den entsprechenden Java-Host-Variablen zugewiesen werden. Die Zuweisung erfolgt auf der Basis der Position:Der erste Spaltenwert wird dem ersten Attribut zugewiesen, der zweite dem zweitenusw. Aus diesem Grund muss die Anzahl der Host-Variablen in der FETCH-Anwei-sung gleich der Anzahl der Spalten in der SELECT-Liste sein.

Positionierte Iteratoren verwenden die Methode endFetch(), um das Ende einer Ergeb-nismenge zu ermitteln. Diese Methode liefert den Booleschen Wert true, falls keine wei-teren Reihen der Ergebnismenge geholt werden können.

7���++�������(8�������� ��6���*���������95:�;���!���

Der enge Zusammenhang zwischen JDBC-ResultSet und Iteratoren wird besondersdadurch deutlich, dass man diese untereinander konvertieren kann.

Um einen Iterator (benannt oder positioniert) in eine Instanz der ResultSet-Klasseumzuwandeln, wird die Methode getResultSet() des Iterators folgendermaßen ver-wendet:

�����*� *& ��� �& 8���* ��7����* ��7����* ��7��!�� �& 8��� �!���0���*��*� ��,��� ��7�*0���*��*��!

Es ist bei einer derartigen Konvertierung zu beachten, dass man den Iterator nicht ver-wendet, sondern über die definierte Instanz der ResultSet-Klasse darauf zugreift.Sobald der Iterator geschlossen wird, wird auch die Instanz der ResultSet-Klassegeschlossen. (Die Instanz muss nicht explizit nach ihrer Verwendung geschlossen wer-den.)

Um eine Instanz der Klasse ResultSet in einen Iterator (benannt oder positioniert) zukonvertieren, wird der CAST-Operator verwendet:

0���*��*� ��,���*+*��9���*���!������ ��,������.�< ���!

Hier ist zu beachten, dass die Instanz der ResultSet-Klasse nicht verarbeitet werdendarf und diese geschlossen wird, sobald der Iterator geschlossen wird. Das Schließender Instanz wird den Iterator jedoch nicht schließen. Bei Verwendung von CAST muss

�������

Die Iterator-Instanz in einer FETCH-Anweisung muss immer »:« als Präfix haben,weil jede Iterator-Instanz eine Java-Variable ist. Innerhalb einer SQLJ-Anweisung(wie FETCH) wird sie als Host-Variable betrachtet.

Page 270: Java in Datenbanksystemen

��- ������������� ��

der Iterator als öffentlich (public) deklariert werden. Die Ergebnismenge, welche immereine Instanz der ResultSet-Klasse sein muss, muss mindestens so viele Spalten enthal-ten wie der benannte Iterator. Genauso müssen die Spaltentypen der Ergebnismengeund des benannten Iterators übereinstimmen. Bei einem positioniertem Iterator müs-sen die Anzahl der Spalten sowie deren Typen übereinstimmen.

Die Deklarationssyntax eines (benannten bzw. positionierten) Iterators kann wesent-lich komplexer sein als in den beiden vorherigen Beispielen. Der nächste Abschnitterläutert weitere Angaben, die ein Iterator enthalten kann.

9��9�<!���*���=��>������6���*��

Die Deklarationssyntax eines benannten Iterators sieht folgendermaßen aus:

����B����*' >��*C��*� D�+���*� D>����D�+�

����B�+��+��*�%L���C�B��*�%L���C��** �'�*��D��*��

Die optionale Angabe sichtbarkeit kennzeichnet eine von den Angaben public, pri-vate, protected oder static. iter_name spezifiziert den Namen der Iterator-Klasse, wäh-rend implements-Klausel die Java-Schnittstellen auflistet, die die Iterator-Klasseimplementieren wird. (Wir erinnern noch einmal daran, dass eine Java-Schnittstelle imUnterschied zu Java-Klassen die in ihr angegebenen Methoden nicht implementiert.Diese Aufgabe wird von einer Klasse übernommen, deren Name der implements-Klausel vorangeht.)

Die with-Klausel ermöglicht die Definition und die Initialisierung von Konstanten, diein der Definition der generierten Iterator-Klasse eingefügt werden. Die Syntax dieserKlausel ist:

��*��� �'�8�,��� *8��� �'�O�,��� *O��������� �'�9�,��� *9

Der Standard-SQLJ enthält eine Liste von vordefinierten Konstanten, die mit der with-Klausel definiert werden können. (Die meisten von ihnen beziehen sich auf denZustand eines Cursors.) Ein Beispiel mit der implements- und with-Klausel kann imfolgenden Abschnitt (Beispiel 7.10) gesichtet werden.

��&�G )��%�������������������(���/�������>7-$�����#%��-�����$�%������

Für die Änderung von Reihen mit Hilfe einer UPDATE- bzw. DELETE-Anweisung istein Iterator im Allgemeinen nicht notwendig, weil diese Anweisungen keine Ergebnis-menge erstellen und nur die Anzahl der geänderten Reihen zurückliefern. In gewissenFällen ist die Verwendung des Iterators mit diesen beiden SQL-Anweisungen notwen-dig: Falls der Anwender die Entscheidung über das Ändern einzelner Reihe beimAblauf des Programms treffen will, muss ein Iterator verwendet werden. Eine solcherFall wird positioniertes Ändern (positioned update) genannt.

Page 271: Java in Datenbanksystemen

�� ������� ����!���� ��%

Beispiel 7.10 zeigt das positionierte Ändern der Reihen. (Dieses Programm kann nurmit DB2 und Informix verwendet werden, weil Oracle und MySQL zur Zeit dieseFunktionalität nicht unterstützen.)

Beispiel 7.10

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!==�;*� *& �FR �A��*������$��*��� �*��������*� *& ����7��� �& ��+��+��*����(� ��*�+��/& A��*����*�������������*��&�+��, +D� �� D� ��F7'� �����* ��7�+D� ���* ��7� D� ���* ��7��F7'��!��'�������A��*�;*� ������**���F�����*�$H2��,�$HA*���;#/102;�!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!

��������* :���������������������==�FR �0&'�>���*&�&++�*�'���*��<�������������&����*��*&�&++�*�F���!������������$�F�*�&�*�9*���*$�F�*�&�*�9*����$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!���������������7��� �& ��� �!�������������* ��7��* 8!�������������* ��7�+D� !�==1'� 7 ��?��������������* ��7��*�& *!������������==�� ��*�����+���*?���������������F��$H2��,,�$HA*���$HO���������.��A00�#.���4�2��$HO�$2;#��!�������������:�*�+�&�*�� ��*�� K�K�Z�'�������#�++� ����2�* '��*� �����<� �!������������+D� �,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ��������!�������������* ��7�� D� ��F7'�!������������������ ��,��������.�+D� ��� D� ���F7'��/012� '��*��34�0��+D� �,�<+D� /10�A)$�.��1/�+D� �� D� ��F7'���!

DB2, INFORMIX

Page 272: Java in Datenbanksystemen

��� ������������� ��

�������������������� ����9*����������������������* 8�,��� ��+D� ��!�����������������:�*�+�&�*�� ��*�� +D� ,� �"��* 8�!�����������������* 8�,��� ��� D� ��!�����������������:�*�+�&�*�� ��*�� �� D� ,� �"��* 8�!�����������������* 8�,��� ���F7'���!�����������������:�*�+�&�*�� ��*�� ��F7'�,� �"��* 8�!�����������������:�*�+�&�*�� ��*�� K�2&���*�������������0����&��������(=��5K� �!������������������*��,�����H�FF� ��0��� ����;���*�* �+0��� ��:�*�+������ ����!�����������������F��,,_�_�``�,,_(_���������������������������$���.��F &+� '��*���34�0���A00�#.�1/<�� ���!�������������������������������01��H��L��& >��!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.10 ist:

@� '�����7�?��$H�1LZ�'�������#�++� �����2�* '��*� �����<8W8WO+D� ,�8W8WO�� D� ,��8����F7'�,�) &(�>*��*� 2&���*�������������0�����&��������(=��5(+D� ,�8W8WO�� D� ,��O����F7'�,�Z �������*� 2&���*�������������0�����&��������(=��5�

Bei dem Iterator in Beispiel 7.10 handelt sich um eine spezielle Form des benannten Ite-rators. Aus diesem Grund werden wir nur die Unterschiede zwischen dem benanntenIterator (Beispiel 7.8) und dem Iterator für das positionierte Ändern (Beispiel 7.10)erläutern.

Page 273: Java in Datenbanksystemen

�� ������� ����!���� ��.

Der erste wichtige Unterschied betrifft die Iterator-Deklaration:

�����*� *& ����7��� �& ��+��+��*����(� ��*�+��/& A��*����*�����������*��&�+��, +D� �� D� ��F7'� ����* ��7�+D� ���* ��7� D� ���* ��7��F7'��!

Ein Iterator, der für das positionierte Ändern verwendet werden soll, muss die imple-ments-Klausel enthalten, die sich in diesem Fall auf die Klasse sqlj.runtime.ForUp-date bezieht. (Für die Beschreibung aller Angaben der implements-Klausel siehe denvorherigen Abschnitt.) Die zweite Klausel heißt with-Klausel und enthält im Falleeiner positionierten Änderung die updateColumns-Spezifikation mit der Liste alleränderbaren Spalten der Tabelle.

Der nächste wichtige Unterschied betrifft die Erstellung der Verbindung zwischen derErgebnismenge, die positioniert geändert werden soll und der Iterator-Instanz:

������ ��,������.�+D� �� D� ��F7'��/012� '��*���34�0��+D� ,<+D� ������������������������/10�A)$�.��1/�+D� �� D� ��F7'���!

In der obigen SQLJ-Ausführungsklausel existiert eine zusätzliche Angabe – FORUPDATE –, die generell folgende Syntax hat:

/10�A)$�.��B1/���*��D��*�C

Mit dieser Angabe werden die ausgewählten Reihen mit Hilfe eines Iterators geändertbzw. gelöscht. spalten_liste definiert die Spalten, die geändert werden können. (Fallsspalten_liste ausgelassen wird, kann jede Spalte der Tabelle geändert werden.)

Die Voraussetzung für das Ändern der Datenwerte bzw. das Löschen der Reihen istdas Vorhandensein der CURRENT OF-Angabe innerhalb der UPDATE- bzw. DELETE-Anweisung. In Beispiel 7.10 existiert eine solche DELETE-Anweisung, weil wir posi-tioniert die Reihen der Tabelle arbeiten löschen wollen:

������$���.��F &+� '��*���34�0���A00�#.�1/�<�� ���!

Die Syntax einer UPDATE-Anweisung für das positionierte Ändern sieht folgender-maßen aus:

�����A)$�.��*'D�+������������.����*�8�,���� ��>8������34�0���A00�#.�1/�<�*� �!

��&��@ 0������������7�(#�������������

Gespeicherte Prozeduren werden innerhalb eines SQLJ-Programms mit Hilfe derCALL-Anweisung aufgerufen. Diese Anweisung ist die allgemein bekannte SQL-Anweisung, die auch in prozeduralen Erweiterungen von SQL bei Oracle (PL/SQL)und Informix (SPL) verwendet wird. Beispiel 7.11 zeigt die Erstellung und den Aufrufeiner gespeicherten Prozedur in einer Oracle-Umgebung. Die Prozedur wird dabei inPL/SQL implementiert.

Page 274: Java in Datenbanksystemen

��� ������������� ��

Beispiel 7.11

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!��'���������)������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!�����**����**�+��*��*+*�,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������$�F�*�&�*�9*���*$�F�*�&�*�9*�����������������$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!�������������*+*�,��&��� �*��**�+��*��!�������������*+*��9���*�� �0��.��10�0�)�����)01��$A0��� �&���D+�**���������������� &?��*���*�$�/�A�.�W�����H�Z;#����*��� &(�>*���������������*�+�**��,�+�**��"��+�**�T� &?��*=8WW�!��#$! �!��������������*�+�**��,�X!������������������������ �&���D+�**��<+�**����!�������������:�*�+�&�*�� ��*�� ) &?��� ���7�FR� * �!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!

�������

Gespeicherte Prozeduren können nicht nur mit Hilfe der prozeduralen Erweiterungdes jeweiligen Datenbanksystems implementiert werden. SQLJ bzw. JDBC könnengenauso für ihre Implementierung verwendet werden. Kapitel 10 beschreibt dieseArt der Implementierung.

ORACLE

Page 275: Java in Datenbanksystemen

�� ������� ����!���� ��,

��������������� ��*�*�>. ����!��������������==������&��2���

Die Ausgabe des Beispiels 7.11 ist:

@� '�����7�?��$H�1L) &?��� ���7�FR� *

Mit Hilfe der Anweisung:

�*+*��9���*�� �0��.��10�0�)�����)01��$A0��� �&���D+�**��� &?��*���*�$�/�A�.�W�����H�Z;#����*��� &(�>*���*�+�**��,�+�**��"��+�**�T� &?��*=8WW�!��#$! �!

wird eine gespeicherte Prozedur im Datenbanksystem erzeugt. Der Aufruf dieser Pro-zedur erfolgt folgendermaßen:

������������ �&���D+�**��<+�**����!

Mit der CALL-Anweisung wird die gespeicherte Prozedur namens erhoehe_mittelaufgerufen. Der einzige Parameter dieser Prozedur wird als Host-Variable innerhalbder SQLJ-Klausel verwendet.

Das folgende Beispiel zeigt die Implementierung einer gespeicherten Funktion.

Beispiel 7.12

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�T!��'�������@����)������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!�����**����**�+��*��*+*�,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT������'����**����&���+����* ��7� 7�BC�

�������

Mit MySQL ist es nicht möglich, ein SQLJ-Programm wie in Beispiel 7.11 zu imple-mentieren, weil dieses Datenbanksystem keine gespeicherte Prozeduren unter-stützt.

ORACLE

Page 276: Java in Datenbanksystemen

��� ������������� ��

��������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������$�F�*�&�*�9*���*$�F�*�&�*�9*�����������������$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!�������������*+*�,��&��� �*��**�+��*��!�������������*+*��9���*�� �0��.��10�0�)�����/A#�.;1#�7�*�� &�����������������/�1�.��0�.A0#��/�1�.����H�Z;#�������������0�.A0#����=8�8�^XX\MW!��#$! �!������������F&*�$2'�* 7�,�X!������������F&*� ���*,W!���������������� ���*�,���@��A���7�*�� &�<$2'�* 7���!�������������:�*�+�&�*�� ��*�� ) &?��� ���7�FR� *<� " ���*�!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2���

Beispiel 7.12 ist bis auf zwei signifikante Unterschiede identisch mit dem Beispiel 7.11.Eine gespeicherte Funktion wird bei Oracle mit Hilfe der CREATE FUNCTION-Anweisung erstellt. In Beispiel 7.12 wird die Funktion getEuro(), die DM-Beträge inEuro konvertiert, mit Hilfe folgender SQL-Anweisung erstellt:

�*+*��9���*�� �0��.��10�0�)�����/A#�.;1#�7�*�� &�����/�1�.�����������0�.A0#��/�1�.����H�Z;#�0�.A0#����=8�8�^XX\MW!��#$! �!

Im Gegensatz zum Aufruf der gespeicherten Prozeduren, die mit der CALL-Anwei-sung erfolgt (siehe Beispiel 7.11), kann der Aufruf einer gespeicherten Funktion inner-halb eines SQLJ-Programms mit der VALUES-Klausel erfolgen. Die Syntax dieserAnweisung ist:

����� 7�'����,���@��A����/��>*�&���+��I) +�*� ��*�J�����!

Die Variable ergebnis muss dabei dem Rückgabetyp der Funktion entsprechen.

Page 277: Java in Datenbanksystemen

�� ������� ����!���� ���

Dementsprechend sieht der Aufruf der getEuro()-Funktion in Beispiel 7.12 so aus:

���� ���*�,���@��A���7�*�� &�<$2'�* 7���!

Selbstverständlich kann eine gespeicherte Funktion mit einer DML-Anweisung (inner-halb oder außerhalb eines SQLJ-Programms) aufgerufen werden. Folgende Abfrage,z.B.:

�����.�7�*�� &�+�**�����/012�� &(�>*34�0��� D� �;#��_�8_��_�O_�

konvertiert die Mittel der Projekte p1 und p2 in Euro.

��&��� �0�(H��9�=�3��������

Die großen Objekte (large objects – LOB) weisen eine praktisch uneingeschränkte Größeauf. Sie werden benutzt, um Objekte wie Binärdateien, Bilder oder Unicode-Texte ineiner Tabellenspalte zu speichern. (Für die Beschreibung dieser Objekte siehe Kapitel 4.)

Das folgende Beispiel erlaubt die Speicherung beliebiger Bilddateien in einer Daten-banktabelle. In der Tabelle wird der Ursprungspfad der Datei als großes textuellesObjekt, die Datei selbst als großes binäres Objekt gespeichert. Als eindeutige Identifi-kationsnummer (ID) dient eine Spalte mit der Bildbeschreibung. Das Beispiel unter-sucht zuerst, ob eine Datei gespeichert werden soll und danach, ob eine Datei imUrsprungsverzeichnis wiederhergestellt werden soll. Optional kann der Inhalt derDatei direkt oder in der hexadezimalen Form ausgegeben werden.

Beispiel 7.13

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�$�F�*�&�*�9*!==�FR ���1H�����H�1H�+�& *�& ������T!

�������

Bei der Verwendung einer gespeicherten Funktion mit einer SELECT-Anweisunginnerhalb eines SQLJ-Programms muss man speziell bei benannten Iteratoren einenAliasnamen angeben, damit der Zugriff auf diese Spalte möglich wird.

ORACLE

Page 278: Java in Datenbanksystemen

��� ������������� ��

��'��������&'������**���F�����*�$H2��,�$HA*���10����!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT����������'����**����*� *& �;*� ���* ��7�����+�����1H�����*�������H�1H��+7��!������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������==�/R �H�1H��&*�����7U�������������&����*��*&�&++�*�F���!������������$�F�*�&�*�9*���*$�F�*�&�*�9*�����������������$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� H��������� ��7����$*��'�>���������������,���*� �!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!�������������:�*�+�&�*�� ��*�� H��� ����$H�������� ��(=��5 �!�������������F� �������������� ( �������������������*& �)����!�������������:�*�+�&�*�� ��*�� H��� ����$H������������������ �� �*����(=��5 �!�������������* ��7�&�*��*�,� ��������!�������������F�U&�*��*������ ( ����:�*�+��9�*�W�!������������ ��*& �)����!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2������==����������&+�H������ +������'����**����* ��7� �����������������* :������������� �*� ������H�FF� ��0��� �����������������;���*�* �+0��� ��:�*�+������ ��������!����������*����9���*�&�������������� �*� �� !�����

Page 279: Java in Datenbanksystemen

�� ������� ����!���� ��"

����==�H�1H�������1H%$*������$H�����������'����**����&��� ��*& �)�����*� &�������9���*�&�������;1�9���*�&���/��#&*/&����9���*�&������������1H��!��������H�1H�'!��������;*� ��� �!�������������� ��,������*�T�F &+����*'��!��������/��1�*��*�* �+�F&!���������* ��7��*���+�!��������������� ����9*�����������������+��,��� ������+����* �+��!��������������,��� ������*���!������������'�,��� ���+7���!�������������*��,���7�*��'�* ��7�8����*�����7*����!�������������:�*�+�&�*�� ��*�� $*��� "�+�" ����� "�*�" ���������������� ��'���(=��5 �!�������������* ��7�����*�,� ��������!�������������F�U����*������ ( �������������������&�*����!������������F&�,�����/��1�*��*�* �+��*��!������������F&�� �*��'�7�*H:*���8����*�'���7*�������!������������F&��&����!�������������:�*�+�&�*�� ��*�� ���7'����4��%$�+��(=��5 �!����������������*�,� ��������!�������������F�����*������ ( �������������������:�*�+�&�*�� ��*�� 4�9%$�+�<� "��+�H&'�'�* ����!������������������==�H�1H%������1H%$*���������� �������'����**����&����*& �)�����*� &�������9���*�&���;1�9���*�&����������/��;���*�* �+�F��,���!��������'&&���� & !���������* ��7�����*, !���������&�������������� & ,F��!�������������:�*�+�&�*�� ��*�� H�**��7�'�������������$*���+���+�*�������������)F���< �!������������* :���������������������*�,� ��������!�����������������F�����*������ � ����:�*�+��9�*�W�!����������������F��,�����/��;���*�* �+�����*�!��������������*����9���*�&����������������������:�*�+�&�*�� ��*�� /��� �'��+��������� �$*��U �!����������������� & �,�* ��!���������������������������� & �!���������:�*�+�&�*�� ��*�� H�**��7�'������������H���� ��'��7��< �!���������* ��7�����+��,� ��������!���������F�����+������� � ����:�*�+��9�*�W�!��������==�.'���+�*�H�1H�������1H�� �*�����������* :�

Page 280: Java in Datenbanksystemen

��- ������������� ��

�������������������0��.��.�H������*'�������+��@�0�4�0�OXX��������������� �+ :�>�:������*�����1H��+7��H�1H���!����������*����9���*�&����������������*���7*��,�W!��������H�1H�'&'�*!��������==�H�1H%�&�*& �� �*���<��������������;#��0.�;#.1����*'��@��A����<����+���<����*�����������2).aDH�1H�����!��������==�H�1H�FR �b��� ��7������������������������.��+7��;#.1�<'&'�*�/012����*'��34�0��������������+��,�<����+���!��������':*�BC�'�FF� �,�����':*�B'&'�*�7�*����>��?���C!����������*�&FF��*,8!��������&�7�'&'���,�����������������7*��,�F�� ���'�FF� ���U,�%8����������������������==�*?*��H:*�������?���*��>R ?���������������F���7*�I'�FF� ���7*�������������������':*�BC�'*�,�����':*�B��7*�C!����������������F& ���*�*,W!�*I��7*�!�*""���������������������'*B*C�,�'�FF� B*C!����������������'�FF� �,�'*!�������������������������'&'�*���*H:*���&FF��*�'�FF� �!������������&FF��*",��7*�!�����������������F���&����!���������:�*�+�&�*�� ��*�� H���7�������� *K� �!���������==����7'��������H&'�����4�9%$ �*���7�&�� �S����������==�10����%���?�F����������'����**����* ��7���+�H&'�H�1H�'&'��'&&�����9������������* ��73 �*� ����,������* ��73 �*� ��!��������* :�������������;���*�* �+����* �+�,�'&'�7�*H�� :�* �+��!������������':*�BC�'�FF� �,�����':*�B'&'�7�*����>��?���C!��������������*���7*��,�W!���������������������7*��,����* �+� ���'�FF� ���U,�%8����������������������������F& ����*��,W!��I��7*�!��""��������������������':*��'�,�'�FF� B�C!�������������������F���9��������������������������*���,�����*�'��c�W9FF!�����������������������F���I�8]������ �*��_W_�!������������������������ �*��;�*�7� �*&4�9�* ��7����!������������������������������������������������������������ �*��'�!���������������������������������������� �*� �����*&�* ��7��!

Page 281: Java in Datenbanksystemen

�� ������� ����!���� ��%

����������*����9���*�&�������������� �*� �� !������

Die Ausgabe sieht etwa so aus (je nach eingegebenen Daten):

H��������� ��7����$*��'�>���,���*�@� '�����7�?��$H�1LH��� ����$H�������� ��(=��5H��� ����$H������ �� �*����(=��5���7'����4��%$�+��(=��5

Das Beispiel kann nur mit Oracle verwendet werden und benutzt deswegen die spezi-fischen Klassen dieses Systems namens CLOB und BLOB, die eine erweiterte Schnitt-stelle als die Standard-Java-Klassen java.sql.Blob und java.sql.Clob bieten. ZurVerwendung dieser Klassen muss das Paket & ������T�importiert werden.

Die im Beispiel verwendete Tabelle pictable, welche eine Bildbeschreibung, den Bild-pfad und die Bilddaten enthält, wird durch die SQL-Anweisung

�0��.��.�H������*'������+��@�0�4�0�OXX��� �+ :�>�:�����*����1H������������������������+7��H�1H�

erzeugt. Für die spätere Ausgabe des Tabelleninhalts wird deshalb ein benannter Itera-tor mit folgender Anweisung definiert:

������'����**����*� *& �;*� ���* ��7�����+����1H�����*��H�1H��+7��!

Das Hauptprogramm main() ist lediglich für die Verbindung zur Datenbank, die Aus-gabe der Benutzeroberfläche und die Ausnahmebehandlung zuständig, die eigentli-chen Datenbankzugriffe erfolgen in eigenen (statischen) Methoden.

Die Abfrage der Bildschirmeingaben erfolgt der besseren Übersichtlichkeit wegen ineiner eigenen Methode – readLine() –, welche von der Standardeingabe bis zum Zei-lenumbruch liest und die bereits von früher bekannten Klassen (BufferedReader undInputStreamReader) verwendet. Je nach Benutzereingabe werden im Hauptpro-gramm die Methoden storePic() und restorePic() aufgerufen, welche als statischeMethoden der Klasse implementiert sind.

�������

Für die Änderung eines großen Objektes ist es im Beispiel unbedingt notwendig,AutoCommit zu deaktivieren, damit während des Einfügens von Daten in eineLOB-Spalte die Tabelle bis zum Abschluss der Änderung gesperrt wird. (WirdAutoCommit nicht deaktiviert, wird eine Fehlermeldung erscheinen, dass die Zeilemit dem LOB-Inhalt nicht gesperrt wurde.)

Page 282: Java in Datenbanksystemen

��� ������������� ��

Die Methode storePic() speichert den Bildnamen, den Pfad und die Daten in derTabelle. Damit nicht explizit alle möglichen Ausnahmen abgefangen werden müssen,werden diese an die main()-Methode zurückgegeben:

�*& �)�����*� &�������9���*�&���;1�9���*�&�

Die do/while-Schleife wird so lange wiederholt, bis der Benutzer entweder mit demEingabezeichen q abbricht oder einen gültigen Dateipfad eingibt. Dazu wird nach derEingabe des Pfades eine Instanz der Klasse FileInputStream auf die Datei erstellt. Fallsdie Datei nicht vorhanden ist, wird eine Ausnahme erzeugt und die Eingabe muss wie-derholt werden.

Die Variable picname nimmt die Bildbeschreibung auf. (Die gleichnamige Spalte derTabelle wird als Primärschlüssel verwendet, damit ein Bild beim Schreiben bzw. Leseneindeutig identifiziert werden kann.) Beim ersten Programmstart ist die Tabelle nochnicht vorhanden, weshalb in einem try/catch-Block bei jedem Programmdurchlauf ver-sucht wird, diese zu erstellen. Wenn sie nicht vorhanden ist, wird sie erzeugt, anson-sten wird der leere Bereich des catch-Blockes ausgeführt. (Als Alternative bietet sicheine Abfrage der entsprechenden Systemtabelle an.)

Bevor ein großes Objekt gelesen oder geschrieben werden kann, muss es initialisiertwerden. Die Datenbank benötigt einen sogenannten Lokator (locator), der eine Ver-knüpfung zwischen dem großen Objekt und den eigentlich gespeicherten Daten her-stellt. Falls ein solcher Lokator nicht existiert, werden keine Operationen ausgeführt.

Zur Initialisierung bzw. Erstellung eines leeren großen binären Objektes wird beiOracle die Funktion EMPTY_BLOB() angeboten. Mit Hilfe der Anweisung:

�����;#��0.�;#.1����*'��@��A����<����+���<����*���2).aDH�1H����!

wird eine Zeile mit Bildbeschreibung, Bildpfad und einem BLOB-Lokator in derTabelle erstellt. Das große textuelle Objekt wird dabei direkt als Zeichenkette in dieINSERT-Anweisung übernommen. Dies ist bis zu einer sehr kurzen Datenlänge auchbei großen binären Objekten möglich, wobei diese dann als Zeichenkette in der hexa-dezimalen Codierung übergeben werden müssen. Im Allgemeinen werden beideDatentypen (CLOB und BLOB) gerade bei großen Objekten verwendet, weshalb dieVorgehensweise bei der BLOB-Spalte vorgezogen werden sollte.

Das Füllen der Daten in ein binäres großes Objekt kann nicht bei der Initialisierungdurchgeführt werden, sondern muss in einem separaten Schritt geschehen. Das initiali-sierte binäre Objekt wird mit Hilfe des Bildnamens aus der Tabelle gelesen, damit esgefüllt werden kann:

�����������.��+7��;#.1�<'&'�*�/012����*'��34�0������+��,�<����+���!

Page 283: Java in Datenbanksystemen

�� ������� ����!���� ��.

Da die Daten in mehreren kleinen Stücken übertragen werden, kann bei Oracle die opti-male Größe dieser Stücke (chunks) mit Hilfe der Methode getChunkSize() der BLOB-Klasse ermittelt werden. (Diese Funktionalität wird von der Klasse java.sql.Blob nichtgeboten). Die Verwendung der chunk-Größe ermöglicht eine optimale Geschwindigkeitbeim Zugriff auf ein großes binäres Objekt. (Sie ist aber nicht vorgeschrieben.)

Innerhalb der while-Schleife werden diese Datenpakete Stück für Stück über dieMethode putBytes() der Klasse BLOB in die Datenbank übertragen. Damit die letzte,eventuell kürzere Byte-Sequenz korrekt gespeichert wird, verkürzen die Anweisungenim if-Block das zuletzt gelesene Datenpaket auf die korrekte Länge. (Die JDBC-KlasseBlob bietet in dieser Hinsicht keine Unterstützung. Mit dieser Klasse werden lediglichLeseoperationen unterstützt.) Mit der close()-Methode der Klasse FileInputStreamwird schließlich der Eingabestrom geschlossen.

Die Methode restorePic() liest die gespeicherten großen Objekte aus der Datenbankaus und speichert die Bilddaten in einer Datei. Damit die Ausnahmebehandlung nichtwiederholt in dieser Methode implementiert werden muss (und die Übersichtlichkeitgewahrt bleibt), werden alle Ausnahmen an die main()-Methode zurückgegeben. Mitder Anweisung:

������ ��,������*�T�F &+����*'��!

wird der Tabelleninhalt in den zu Beginn definierten Cursor curs eingelesen. Mit Hilfeder Iterator-Methoden picname(), picpath() und image() können die jeweiligen Daten-typen String, CLOB und BLOB gelesen werden. Die Zuweisung:

�*��,���7�*��'�* ��7�8����*�����7*����!

liest den kompletten Inhalt des textuellen Objektes in eine Variable vom Typ String.(Die Methode getSubString() existiert in derselben Form auch in der JDBC-KlasseClob.) Falls man sich entscheidet, das Bild im Ursprungspfad wiederherzustellen, wer-den die BLOB-Daten mit:

F&�� �*��'�7�*H:*���8����*�'���7*�������!

in eine Instanz der Klasse FileOutputStream ausgegeben, andernfalls wird mit demnächsten Bild fortgefahren. Die Methode getBytes() liest ab der angegebenen Positionbis zur spezifizierten Länge aus dem großen binären Objekt in einen Vektor, der ausEin-Byte-Elementen besteht.

�������

Die Methode getSubString() existiert in derselben Form auch in der JDBC-KlasseBlob. Die Länge des großen binären Objektes kann dabei durch die in der Klassejava.sql.Blob ebenfalls definierte Methode length() ermittelt werden.

Page 284: Java in Datenbanksystemen

��� ������������� ��

Optional kann nach der Speicherung noch gewählt werden, ob die BLOB-Daten amBildschirm ausgegeben werden sollen. Dies geschieht mit Hilfe der Methode dump-Blob(), welche als Parameter ein großes binäres Objekt bekommt. Der zweite Parame-ter gibt an, ob die Ausgabe in der hexadezimalen Form oder ohne Vorbereitung (rawdump) erfolgen soll.

Über die Methode getBinaryStream() der JDBC-Klasse Blob wird der Eingabestromdes Objektes ermittelt. In der while-Schleife werden mit:

��7*��,����* �+� ���'�FF� �

die einzelnen Datenpakete ausgelesen und entweder direkt in eine Instanz der KlasseStringWriter geschrieben oder vorher in die hexadezimale Form umgewandelt. Diekomplette Zeichenkette wird dann aus der StringWriter-Instanz gelesen und zurück-gegeben.

Beispiel 7.14 zeigt, wie große Objekte mit MySQL erstellt, gelesen und ausgegebenwerden können.

Beispiel 7.14

��>7������!�+�& *�A*���T!�+�& *�(���&�T!�+�& *�(�����T!�+�& *���(� ��*�+��T!�+�& *���(� ��*�+�� �F�$�F�*�&�*�9*!��'��������&'O������**���F�����*�$H2��,�$HA*���2a���!����=='��Q*�7*��@ �'���FR �$H%S�7 �FFTTT�����**����&����*�&���&��,���!�����**����**�+��*��*+*�,���!�����**���0���*��*� ��,���!����==TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT����������'����**����*� *& �;*� ���* ��7�����+���H�� :�* �+���������*���H&'��+7��!������'����**����&���+����* ��7� 7�BC���������������F��U$HA*������*$*'��$ ��� �$H2���� �*� �!���������F����&��,�$HA*����&����*$*H���$H2����,,����� �*� �!��������* :���������������������$�F�*�&�*�9*���*$�F�*�&�*�9*�����������������$�F�*�&�*�9*��&���!�������������:�*�+�&�*�� ��*�� H��������� ��7����$*��'�>���������������,���*� �!�������������:�*�+�&�*�� ��*�� @� '�����7�?��$H�1LK� �!

MySQL

Page 285: Java in Datenbanksystemen

�� ������� ����!���� ��,

�������������:�*�+�&�*�� ��*�� H��� ����$H�������� ��(=��5 �!�������������F� �������������� ( �������������������*& �)����!�������������:�*�+�&�*�� ��*�� H��� ����$H������������������ �� �*����(=��5 �!�������������* ��7�&�*��*�,� ��������!�������������F�U&�*��*������ ( ����:�*�+��9�*�W�!������������ ��*& �)����!������������==�'������ '��*��TTTTTTTTTTTTTTTTTTTTTTTTTTTT�������������&���&����!�����������������==���FR� ������$H�%/��� '������7<%%%%%%%%%%%%%��������==�����%2�*�&������ F�����*�����������9���*�&����������*�������9���*�&�������������������������$HA*�����&�����9���*�&����!������������������*����9���*�&������������������:�*�+�&�*�� ��*�� K�%%%�/��� ����7�* �*���%%%K� �!��������������� ��*�*�>. ����!��������������==������&��2��������'����**����* ��7� �����������������* :������������� �*� ������H�FF� ��0��� �����������������;���*�* �+0��� ��:�*�+������ ��������!����������*����9���*�&�������������� �*� �� !���������==�H&'������&'%$*������$H�����������'����**����&��� ��*& �)�����*� &�������9���*�&�������;1�9���*�&���/��#&*/&����9���*�&����������;���*�* �+���!��������H&'�'!����������*��!��������/��1�*��*�* �+�F&!���������* ��7��+�!��������;*� ��� �!�������������� ��,������*�T�F &+����*'��!��������������� ����9*�����������������* ��73 �*� ����,������* ��73 �*� ��!�������������+��,��� ������+����* �+��!������������'�,��� ���+7���!������������==��* �+��& ��G���*� �7�*999%2�*�&������������������������,��� ������*���!������������==��* �+��� ����� �����* ��7�>&��� *�� *�������������������,��� �����U,%8��������������������� �*����!�������������:�*�+�&�*�� ��*�� H��� "�+�" ����� "��" ���������������� ��'���(=��5 �!�������������* ��7�����*�,� ��������!

Page 286: Java in Datenbanksystemen

��� ������������� ��

�������������F�U����*������ ( �������������������&�*����!������������F&�,�����/��1�*��*�* �+����*&�* ��7���!������������F&�� �*��'�7�*H:*���8����*�'���7*�������!������������F&��&����!�������������:�*�+�&�*�� ��*�� ���7'����4��%$�+��(=��5 �!����������������*�,� ��������!�������������F�����*������ ( �������������������:�*�+�&�*�� ��*�� 4�9%$�+�<����������������� "��+�H&'�'�* ����!������������������==�H&'%������1H%$*���������� �������'����**����&����*& �)�����*� &�������9���*�&���;1�9���*�&���9���*�&����������/��;���*�* �+�F��,���!��������'&&���� & !���������* ��7�����*, !����������*���7*�,W!���������&�������������� & ,F��!�������������:�*�+�&�*�� ��*�� H�**��7�'�������������$*���+���������������+�*�)F���< �!������������* :���������������������*�,� ��������!�����������������F�����*������ � ����:�*�+��9�*�W�!����������������/���F�,�����/�������*�!������������������7*��,����*�F���7*���!����������������F��,�����/��;���*�* �+�F�!��������������*����9���*�&����������������������:�*�+�&�*�� ��*�� /��� �'��+��������� �$*��U �!����������������� & �,�* ��!���������������������������� & �!���������:�*�+�&�*�� ��*�� H�**��7�'������������H���� ��'��7��< �!���������* ��7�����+��,� ��������!���������F�����+������� � ����:�*�+��9�*�W�!��������==�.'���+�*�H&'�� �*�����������* :��������������������0��.��.�H������*'�������+��@�0�4�0�OXX��������������� �+ :�>�:������*��H�1H���+7���1#ZH�1H���!����������*����9���*�&��������������H�� :�* �+�'��,�����H�� :�* �+�F�����7*��!��������������;#��0.�;#.1����*'��@��A����<����+���<����*��<'���!��������F���&����!���������:�*�+�&�*�� ��*�� H���7�������� *K� �!���������==����7'��������H&'�����4�9$ �*���7�&�� �S������������'����**����* ��7���+�H&'�H&'�'&'��'&&�����9������������* ��73 �*� ����,������* ��73 �*� ��!��������* :�

Page 287: Java in Datenbanksystemen

�� ������� ����!���� ���

��������������;���*�* �+����* �+�,�'&'�7�*H�� :�* �+��!������������':*�BC�'�FF� �,�����':*�B8WWC!��������������*���7*��,�W!���������������������7*��,����* �+� ���'�FF� ���U,�%8����������������������������F& ����*��,W!��I��7*�!��""��������������������':*��'�,�'�FF� B�C!�������������������F���9��������������������������*���,�����*�'��c�W9FF!�����������������������F���I�8]������ �*��_W_�!������������������������ �*��;�*�7� �*&4�9�* ��7����!������������������������������������������������������������ �*��'�!���������������������������������������� �*� �����*&�* ��7��!����������*����9���*�&�������������� �*� �� !������

Beispiel 7.13 hat Ähnlichkeiten mit dem Beispiel 7.12. Aus diesem Grund werden wirnur die Unterschiede zu diesem Beispiel beschreiben.

Im Unterschied zu den anderen Datenbanksystemen kennt MySQL-System folgendeDatentypen für binäre Objekte:

� BLOB

� LONGBLOB.

Wie aus der obigen Liste ersichtlich, kennt MySQL keinen Datentyp CLOB. Der Daten-typ BLOB kann benutzt werden, um große Objekte bis 64 KB zu speichern. LONG-BLOB dagegen speichert alle Objekte bis 4 GB. (Damit entspricht LONGBLOB demDatentyp BLOB bei den anderen Datenbanksystemen.)

Zunächst zu den Änderungen mit Hilfe der Methode restorePic(), die genau in dieserWeise auch mit Oracle funktioniert.

Da der CLOB-Datentyp von MySQL nicht unterstützt wird und die Pfadinformatio-nen, also Text, vom Datentyp BLOB sein sollen, wird die Instanz der Klasse Blob direktin eine Instanz der Klasse InputStream gelesen, und zwar über die Anweisung:

���,��� ������*���!

Diese Vorgehensweise, mit der das Auslesen der großen textuellen Objekte sehrelegant gelöst ist, ist nicht spezifisch für MySQL, sondern funktioniert auch z.B. mitOracle.

Page 288: Java in Datenbanksystemen

��� ������������� ��

Nach JDBC-Konventionen darf ein derartiger Strom nur bis zur Verwendung dernächsten getXXX()-Methode verwendet werden, weshalb die Instanz der Blob-Klassebereits vorher über die image()-Methode gelesen wurde.

Mit der anschließenden while-Anweisung:

�������,��� �����U,%8���������� �*����!

wird der Strom aus der Instanz is in einen Strom der Klasse StringWriter kopiert. DieStringWriter-Klasse ist sehr effektiv beim Konkatenieren von Zeichenketten underlaubt die Verwendung der endgültigen String-Instanz über deren toString()%Methode, wie sie im Beispiel im Konstruktor des FileOutputStreams verwendetwurde.

Beim Speichern eines großen binären Objektes wird die Methode storePic() anders ver-wendet als im Oracle-Beispiel. Die Daten der Eingabedatei werden direkt einem Bi-naryStream-Objekt übergeben, welches über die Anweisung:

H�� :�* �+�'��,�����H�� :�* �+�F�����7*��!

erzeugt wird. Die Länge des Stromes wird über die length()-Methode des File-Objek-tes, beim Öffnen der Eingabedatei, ermittelt. Mit Hilfe der Anweisung:

������;#��0.�;#.1����*'��@��A����<����+���<����*��<'���!

kann dann dieser Stream direkt als Host-Variable angegeben werden. Die kurze Zei-chenkette für den Pfadnamen, der als großes binäres Objekt gespeichert wird, kannwieder direkt als eine String-Instanz übernommen werden.

��* 8���//�� ������

SQLJ ist nach JDBC die zweite Java-Schnittstelle, die für die Datenbankprogrammie-rung verwendet werden kann. Obwohl SQLJ nur die Programmierung der statischenSQL-Anweisungen ermöglicht, hat sie einige wichtige Vorteile im Vergleich zu JDBC:

� SQLJ befindet sich auf einem höherem logischen Niveau als JDBC

� SQLJ hat eine einfachere Syntax als JDBC

� SQLJ kann die Syntax- und Semantikanalyse zur Übersetzungszeit durchführen.

Das nächste Kapitel beschreibt, wie die objektorientierten Erweiterungen mit SQLJimplementiert werden können.

Page 289: Java in Datenbanksystemen

� ���������� ���� ��� �� ���� �� ���� �

Die Basis für dieses Kapitel sind in Kapitel 2 erläuterte objektorientierte Erweiterungender SQL-Sprache. Im ersten Teil des Kapitels werden alle Erweiterungen bei Oracle mitHilfe mehrerer SQLJ-Programme dargestellt. Danach erfolgt der Abschnitt mit SQLJ-Programmen für Erweiterungen bei Informix. (Weil IBM DB2 noch immer keine objekt-orientierten Erweiterungen in SQLJ unterstützt, wird dieses Kapitel keinen DB2-Abschnitt enthalten.)

��� ���������� ���� ��� �� ���� �� ���� ��� �������

In diesem Abschnitt werden folgende objektorientierten Erweiterungen bei Oracle mitHilfe mehrerer SQLJ-Programme dargestellt:

� der Objekttyp

� der Datentyp REF

� die VARRAY-Kollektion

� geschachtelte Tabellen.

Der erste Abschnitt zeigt die Verwendung des Objekttyps und des Datentyps REF,während zwei weitere Abschnitte Oracle-Kollektionen (Vektoren und geschachtelteTabellen) behandeln.

����� ����� ������������������� ��� !�"� ����

Beispiel 8.1 zeigt die Verwendung des REF-Datentyps und der CREATE TYPE-Anwei-sung mit SQLJ.

Page 290: Java in Datenbanksystemen

��� ������������ ����� �����������������������

Beispiel 8.1

������������ ��������������� ����������������������������������� ��������������������������������� �!���������"�#$ ����%%&��'��(���)����&����*����+,�(��������������������������������!��� ����%%�����������������������������������������%%�-���.�/�������������$0+$���������1����&������������������/����2 ����(����(�&�3� ����(������30���������3���&����������&4 ������&������������.�����2 ����(���(�564���������������2�7��������������&��������2��� 44������� ����������2�2����!���������������������2��� 44�!!���4������� ����������8���������������������%%�������+)��&��.��(9��������*�� :#;�����(�������������������������������������������2��<�������������2���44 ������������ 8��������������2=)��&��.��(�>������?=4 ������������%%��������@�&�����.�@8��'�A����������������8�����������������1�������B�@"�#$���&�����C�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1�������B�@"�#$������9�C�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1�������B�@"�#$������&�����C�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8����������������1�������B�@EB$���&�������8��D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1�������B�@EB$������9���8��D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1�������B�@EB$������&�������8��D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D������������%%�@�&������.�@8����������������������1������$"@$�@EB$������&�������8��" ���;$�@�2��������3��������A��2FG43������������A��2FG43��&������A��2FG44�D ������������ 8��������������2=�����&�������8�������=4 ������������1������$"@$�@EB$������9���8��" ���;$�@��2������A��2H43����������A��2FI43�����������2CFJ44�D

ORACLE

Page 291: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

������������ 8��������������2=�����9���8�������=4 ������������1������$"@$�@EB$���&�������8��" ���;$�@�2�����/-@3�������K"�2H43����(�&���K"�2FI43������.����"@$3��������������&������$0������&�������8�3���&������$0������9���8�4D ������������ 8��������������2=��&�������8�������=4 ������������1������$"@$�@"�#$������&�����C��0������&�������8��D ������������ 8��������������2=�����&�����C������=4 ������������1������$"@$�@"�#$������9�C��0������9���8��D ������������ 8��������������2=�����9�C������=4 ������������1������$"@$�@"�#$���&�����C��0���&�������8��D ������������ 8��������������2=��&�����C������L�=4 ������������%%�����������*(��������������1��������������������&�����C2����3�������3����������3�&����4������������������&������D ������������1��������������������9�C2�����3��������3������4�����������������9���D ������������1�����������������&�����C2����3������3����(�&�3�����.��3��&����3���&����4��������������������������3�������3�����(�&�3��������.��3����2�43����2�4��������&�������3������9�C��3������&�����C��<A�����������!����������.���������!����������D ������������%%�?�����.��>���$�����(�������&�������.���&�������M������������%%����&�+���! ��@@%��(���+�!�����&�������8�M��&����������������%%�-���.�/�����������������.��*��������������/������� ������������1�����!� $#$�@������(�&��" ����(�&�3�����&������������" ������3�����&�����������" ������3������&�����" ��&�0������&�����C����NK$�$������.���O�PC�C�CQRRP�D ������������%%�������A�����(�&��3������.�����S�.���������������<A��2��������244�����������������%%��������>�&��9�����������������������&����������!�������&24 ����������������%%��������>�������&��9������$0����������������������&�������!���(��)���24 ������������������2��(���-���24�����24�����2=��>��=44���������������������%%�/�A���������&�������(�&���������������������������"���/@2�4 ��������������������%%�-��������&��9��S�.����������������������������-���2=����=4 ��������������������%%��������>�&��9���9���������������������������������)���2�4 ��������������������������!���(���-�24����)���24 �������������������� 8��������������2=T�.������>����������=4 ��������������������1�����B�"@$���&�����C� $@���&�����!�M��NK$�$����!M��D ����������������D������������D������������1�����!� $#$�@������(�&��" ����(�&�3�����&������������" ������3�����&�����������" ������3������&�����" ���&�0������&�����C����NK$�$������.���O�PC�C�CQRRP�D ������������ 8��������������2=������(����L�=4

Page 292: Java in Datenbanksystemen

��� ������������ ����� �����������������������

������������%%�������A������A�����(�&��������������<A��2��������244������������������2������&24�(��)���24�(���-���24�����24�����2=����=44�������������������������"���/@2������&24�(��)���244 ������������%%�"&�A���&�����������������������������������������������������24 �������������������24 ��������D��������%%�"��*A���A��;���+0�A��&�A��.��(M+++++++++++++++��������%%���� :#+���A�.���<���������������� :#$��������������������A2 :#$����������4���������������������������A�< :#$��������2�4 ��������D������������A2$����������4������������� 8��������������2=L�+++���&�9�������0�A���+++L�=4 ������������������� ���9@����24 ��������D����D����%%$�.��������������%%�K�����9�����>���"�>��(��.��������������&����������&������������.������"���/@2��&������4�����������8����������������� 8��������������2��(���-�24U=�=U��(���)������24U=�=U��(���-���24U=�=U��(��"&�-�244 ��������D����A2 :#$����������4�������������������A�< :#$��������2�4 ��������D����DD

Die Ausgabe des Beispiels 8.1 sieht folgendermaßen aus:

"�(�&�������������M++++++++++++++++++++)��&��.��(�>������?�����&�������8������������9���8���������&�������8������������&�����C�����������9�C��������&�����C������FRIIQ� �&������������������>�������������������C"�.������>����������������(����FRIIQ� �&�������������������������������������CFRIIQ� �&�������������������������������������C

Page 293: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

Zu Beginn des SQLJ-Programms in Beispiel 8.1 wird mit Hilfe der import-Anweisungdie Klasse sqlj.runtime.ref.DefaultContext für den Standard-Kontext importiert. Diezweite import-Anweisung bindet das Paket java.sql wegen der Klassen SQLExcep-tion und Connection ein.

Durch die Anweisung:

1����&������������������/����2 ����(����(�&�3� ����(������3�0���������3���&����������&4

wird eine Instanz eines benannten Iterators für den Zugriff auf die später mit SELECTabgefragten Spalten deklariert. (Neben der statischen Deklaration innerhalb derHauptklasse wäre auch eine Deklaration außerhalb der Klasse möglich. In diesem Fallmüssen die Angaben public und static entfernt werden.) Nach dem Vorübersetzen desBeispiels 8.1 wird eine Klasse für den Iterator erzeugt.

Bei der Iterator-Instanz Iter handelt sich um einen benannten Iterator. Alle Spalten bisauf die letzte haben Standarddatentypen, für die keine besonderen Vorkehrungengetroffen werden müssen. Der Datentyp der letztgenannten Spalte ist allerdings einREF-Datentyp, der nicht ohne weiteres verwendet werden kann. In Beispiel 8.1 wurdemit Hilfe des Oracle-Tools Jpublisher ein neuer Java-Datentyp namens arb_mitReferzeugt, der den aus der Datenbank gelesenen REF-Datentyp im Programm repräsen-tiert. (jpublisher wird mit dem Kommando jpub aufgerufen.) Um diesen Typ automa-tisch zu generieren verwendet man folgenden Befehl:

���&�+���! ��@@%��(���+�!�����&�������8�M��&����

Jpublisher ist ein Hilfsprogramm des Oracle-Systems, das im bin-Verzeichnis desSystems zu finden ist. Dieses Hilfsprogramm übernimmt als Eingabe einen in derDatenbank vorhandenen Objekttyp und wandelt diesen in eine Java-Instanz um.(Die Objekttypen, die als Eingabe in Beispiel 8.1 verwendet wurden, heißenmitarbeiter_typ, projekt_typ und arbeiten_typ.)

Damit die Klassen generiert werden können, müssen sie zuerst in der Datenbank vor-handen sein. Das SQLJ-Programm namens Create.Types.sqlj, das sich auf der CD-ROM befindet, erstellt und speichert alle in diesem Abschnitt benötigten Oracle-Objekttypen in die Datenbank.

Die Option -user des jpub-Kommandos gibt den Benutzernamen und dessen Kenn-wort an. Befindet sich der Datenbank-Server auf einem anderen als dem lokalen Rech-ner, so kann man auch eine explizite Server-Adresse angeben. Der Parameter -sqlenthält alle Datenbanktypen, die für einen Zugriff mit JDBC konvertiert werden sollen,

�������

Mit dem Programm CreateTypes.sqlj werden auch die notwendigen Objekte fürJDBC einfach erzeugt.

Page 294: Java in Datenbanksystemen

��� ������������ ����� �����������������������

getrennt durch Komma. Gibt man hinter einem Typ einen Doppelpunkt an, so kannman den Namen des konvertierten Typs spezifizieren. (In unserem Fall heißt der Typarb_mit.)

Das oben angegebene Kommando erzeugt zwei Dateien: arb_mitRef.java undarb_mit.sqlj. Zuerst muss man die arb_mit.sqlj-Datei vorübersetzen und anschlie-ßend übersetzen und danach die arb_mitRef.java-Datei übersetzen. Damit steht einJava-Objekt zur Verfügung, um das REF-Objekt mit SQLJ auslesen zu können.

Nachdem die Datenbankverbindung wie üblich hergestellt wurde, benötigt man einenKontext. In diesem Fall verwenden wir einen Standard-Kontext, der aus dem Connec-tion-Objekt erzeugt wird:

�����������������������������2��<��������������2���44

Für eine mehrfache Ausführung des Beispiels werden alle erstellten Datentypen undTabellen, die eventuell noch in der Datenbank vorhanden sind, gelöscht. Falls dabei einFehler auftritt, wird dies in einem try-catch-Block, der jede DROP-Anweisung umgibt,abgefangen. Die Methode DBUtils.showSQLException() zeigt dabei die aufgetretenenFehler an. Normalerweise entstehen für unterschiedliche Datenbanksysteme verschie-dene Fehler-Codes, die man dann explizit abfragen kann.

Danach werden die für die Übung benötigten Typen und Tabellen erstellt, sowie Dateneingefügt. Das Beispiel lehnt sich dabei an die entsprechenden Beispiele in Kapitel 2 an(siehe Beispiele 2.21 und 2.22). Zu beachten ist hierbei, dass die Typen in der Reihen-folge vom allgemeinen bis zum speziellsten Typ erstellt werden müssen. (Dementspre-chend muss bei den vorangegangenen DROP-Anweisungen zuerst der speziellste bishin zum allgemeinsten Typen gelöscht werden, um keine Fehler zu verursachen.)

Der Vorteil von SQLJ (im Vergleich zu JDBC) wird in Verbindung mit der INSERT-Anweisung offensichtlich, da hier nicht mehrere Zeichenketten über die Zeilen verteiltwerden müssen und die Anweisung so dargestellt ist, wie man sie auch direkt übereine interaktive Client-Schnittstelle des Datenbanksystems abschicken kann.

Mit folgenden Anweisungen:

/������� 1������!��� $#$�@������(�&��" ����(�&�3�����&������������" ������3�����&�����������" ������3������&������" ���&�0������&�����C����NK$�$������.���O�PC�C�CQRRP�D

�������

Zu beachten bei Verwendung von jpub ist, dass die Java Virtual Machine (JVM)benötigt wird und die Oracle-spezifischen Archive (.jar-Dateien) im CLASSPATHangegeben sein müssen.

Page 295: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

wird eine Instanz des benannten Iterators deklariert und eine Abfrage ausgeführt, diedas Ergebnis der Instanz zuweist. Hier ist zu beachten, dass wir jeder selektiertenSpalte einen Aliasnamen (mit Hilfe der AS-Angabe) zuweisen, der auch in der Iterator-Deklaration verwendet wurde. Dies ist unbedingt erforderlich, weil vollqualifizierteNamen (also arbeiten1.aufgabe z.B.) in der Iterator-Deklaration nicht verwendet wer-den können.

Bei einem benannten Iterator kann man alle Reihen der Ergebnismenge mit Hilfe dernext()-Methode durchlaufen. Weil es für jede im Iterator deklarierte Spalte eineMethode mit identischem Namen gibt, ist es möglich, die zuvor deklarierte Referenz-Typ-Spalte mit Hilfe der Methode curs.arb() auszulesen. Das gelesene Objekt ent-spricht jedoch nicht dem Referenzinhalt selbst, sondern stellt nur eine Referenz dar.Aus diesem Grund muss mit Hilfe von r.getValue() der eigentliche Inhalt gelesen wer-den. Dies ist nun der mitarbeiter_typ selbst, der hier durch die Verwendung vonJpublisher in arb_mit umbenannt wurde.

Zum Zugriff auf die einzelnen in diesem Typ enthaltenen Werte gibt es jeweils eineeigene Methode, die im von JPublisher erzeugten .sqlj-Code nachgesehen werdenkann. Um z.B. den Wert der Spalte m_name zu lesen, wurde eine Methode getM-Name() erzeugt.

In Beispiel 8.1 wird derjenige Eintrag geändert, der den Namen Mozer trägt. DieErkennung erfolgt über die üblichen String-Methoden. Die aufgerufene MethodeprintARBMIT() dient lediglich dazu, die im Objekttyp mitarbeiter_typ gespeichertenWerte zur Kontrolle auszugeben und ruft dazu alle erzeugten get()-Methoden inner-halb von arb_mit auf. Für jede get()-Methode wurde auch eine entsprechende set()-Methode erzeugt, mit deren Hilfe ein neuer Mitarbeitername durch:

�����-���2=����V4

eingetragen wird.

Zu diesem Zeitpunkt ist der Inhalt des arb_mit-Objektes aktualisiert, jedoch nicht dasReferenzobjekt, das durch r.setValue(a) geändert wird. Nur dieses Referenzobjekt kannmit Hilfe der UPDATE-Anweisung in die Datenbank gespeichert werden. Dazu wirdder Spalte arb_mit das entsprechende Java-Objekt zugewiesen. Dabei wird die aktu-elle Mitarbeiternummer zur eindeutigen Identifizierung der zu aktualisierenden Reihein der Datenbank verwendet. Die abschließenden Programmzeilen wiederholen dieganze Prozedur noch einmal, um die geänderten Werte zur Bestätigung noch einmalzu lesen und auszugeben.

Page 296: Java in Datenbanksystemen

�� ������������ ����� �����������������������

����# $%��%&�'�� �� !�� �������

Das folgende Beispiel zeigt ein SQLJ-Programm mit dem VARRAY-Datentyp.

Beispiel 8.2

������������ ��������������� ����������������������������������� �������)����8����������������������� �!���������"�#$ ����%%&��'��(���)����&����*����+,�(��������������������������������!��� ����%%�����������������������������������������%%�-���.�/������������)"��"E+$���������1����&������������������/����2 ����(�����3��A��)����8�����4 ������&������������.�����2 ����(���(�564���������������2�7��������������&��������2��� 44������� ����������2�2����!���������������������2��� 44�!!���4������� ����������8���������������������%%�������+)��&��.��(9��������*�� :#;�����(�������������������������������������������2��<�������������2���44 ������������ 8��������������2=)��&��.��(�>������?=4 ������������%%��������@�&�����.�@8��'�A����������������8�����������������1�������B�@"�#$�������D ������������D����A2$����������4�D��������������8�����������������1�������B�@EB$��A��������8�D ������������D����A2$����������4�D������������%%�@�&�������������.�����������*(��������������1�����$"@$�@EB$��A��������8�/ �)"��"E2J4��0��K"�2WG4D ������������1�����$"@$�@"�#$�������2������K"�2WG43������A��������8�4�D ������������1����/- $�@�/-@��������)"#�$ �2P��NP3�A��������82P�*��A��P3P/�(���.�P3PX&����P4�4�D ������������1����/- $�@�/-@��������)"#�$ �2P"�.�P3�A��������82P ����(���P3P���(����(P3P/�.���P4�4�D ������������1����/- $�@�/-@��������)"#�$ �2P����&�A�P3�A��������82P@�9��P3P#��.��P3PK��&��(P44�D ������������%%�?�����.��>���$�����(������A��)����8������������%%����&�+���! ��@@%��(���+�!�A��������8M�A��)����8������������%%�-���.�/�����������������.��*��������������/������� ������������1������!��� $#$�@�������3��������0�����������D

ORACLE

Page 297: Java in Datenbanksystemen

������� ����� ���������������������������������� ��!

������������%%���������(�����M��������������������24 ������������%%�)����8+�&��9�����;���+�&��9������������������A��)����8�����8�!���������24 ������������%%��(�������/�������������*&���.��)"��"E���(�&�������������� 8���������������2="���8��������@8��=�U����8�� :#�-"�$4 ������������ 8���������������2="���8�A���.���#S�(��=�U����8���(�A244 ������������ 8���������������2="���8�������A���.�������8������=�U�����8�(�����@8��-���244 ������������ 8���������������2="���8�������A���.�������8��=�U����8�(�����@8��244 ������������ ����(������ ������������.������������������%%�-�����.���0������*����.����������.����9������������������������!���������24 ���������������� 8��������������2=L�#���)"��"E��*��0����=U�����4 ����������������%%�)"��"E���������������������������8�!���������24 ����������������%%�"� Y"�$�.��)"��"E���������������� ����(�56������!�����8�(��"���824 ��������������������2�����!G ���Z��������(�A ��UU4�������������������� 8�������������2����5�6U=3�=4 ����������������%%�$����������/�.���G����"���8�S�.�����������������������8���$�����2=-�<�E��9=3G4 ����������������%%�)��S�.�����)"��"E�������>��*�9�A���&������������������1����B�"@$������� $@������!�M����8�NK$�$������!M������D ������������D<A���2��������244 ������������%%�$������.������������������3�(�����<����&��������������1������!��� $#$�@�������3��������0�����������D ������������<A���2��������244������������������%%�)"��"E���������.���(�&��3�<����&������������������ 8��������������2=L�#���(�S�.�����)"��"E��*�0�����=U��������244 ��������������������8�!���������24 ���������������� ����(�56������!�����8�(��"���824 ��������������������2�����!G ���Z��������(�A ��UU4�������������������� 8�������������2����5�6U=3�=4 ������������D������������%%"&�A���&��������������������������������������������������24 �������������������24 ��������D��������%%"��*A���A��;���+0�A��&�A��.��(M+++++++++++++��������%%��� :#+���A�.���<���������������� :#$��������������������A2 :#$����������4���������������������������A�< :#$��������2�4

Page 298: Java in Datenbanksystemen

��� ������������ ����� �����������������������

��������D������������A2$����������4������������� 8��������������2=L�+++���&�9�������0�A���+++L�=4 ������������������� ���9@����24 ��������D����D%%$�.����������D

Die Ausgabe ist:

)��&��.��(�>������?"���8��������@8�� ��@@��K"��)"��"E"���8�A���.���#S�(��W"���8�������A���.�������8��������K"�"���8�������A���.�������8��C#���)"��"E��*��0�������N�*��A��������3�/�(���.���������������������3�X&�������������3#���)"��"E��*��0�����"�.� ����(�������3����(����(��������������������3�/�.�������������3#���)"��"E��*��0���������&�A�@�9����������3�#��.��������������������������3�K��&��(����������3#���(�S�.�����)"��"E��*��0�������N-�<�E��9�����3�/�(���.���������������������3�X&��������������3#���(�S�.�����)"��"E��*��0�����"�.�-�<�E��9�����3����(����(��������������������3�/�.���������������3#���(�S�.�����)"��"E��*��0���������&�A�-�<�E��9�����3�#��.��������������������������3�K��&��(�����������3

Wie üblich werden in Beispiel 8.2 zuerst die für SQLJ wichtigen Pakete importiert. Dain diesem Beispiel wieder mehrere Reihen ausgelesen werden, wird erneut eine Itera-tor-Instanz benötigt:

1����&������������������/����2 ����(�����3��A��)����8�����4

Die Instanz des benannten Iterators Iter enthält als ersten Parameter die Spalte mitden Firmennamen, während die zweite Spalte den Vektor mit den jeweiligen Standor-ten der Firma beinhaltet. Damit der Oracle SQL-Datentyp VARRAY in Java verarbeitetwerden kann, benötigen wir wieder eine sogenannte Wrapper-Klasse, die bei Oraclemit dem Werkzeug namens JPublisher erstellt werden kann. (Für die Beschreibungvon Jpublisher siehe Beispiel 8.1). Mit dem Kommando

jpub -user=SCOTT/tiger -sql=char_varray:CharVarray

wird die Java-Klasse CharVarray erstellt, die noch übersetzt werden muss. Aus demerstellten Quell-Code kann man erkennen, dass diese Klasse mehrere Hilfsmethodenbereitstellt, um die Werte der Vektor-Elemente zu lesen und zu ersetzen.

Nach der Initialisierung der Datenbankverbindung und Erstellung des Standard-Kon-textes werden zuerst der zu erstellende Typ (char_varray) und die zu erstellendeTabelle (firma) gelöscht. Danach wird das Objekt char_varray als Vektor mit 6 alpha-

Page 299: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

numerischen Elementen der Länge 30 mit Hilfe der CREATE VARRAY TYPE-Anwei-sung erstellt. Mit Hilfe dieses Vektors wird in der Tabelle firma die Spalte ortedefiniert. (Die zweite Spalte der Tabelle ist eine alphanumerische Spalte.)

Mit Hilfe der INSERT-Anweisung werden anschließend drei Reihen der Tabelle firmaeingefügt. Beim Einfügen der Werte für die Vektor-Spalte orte wird der Objektkon-struktor char_varray aufgerufen. (Für die Beschreibung des Objektkonstruktors sieheKapitel 2.). Die anschließende Abfrage liest mit Hilfe der SELECT-Anweisung alle Rei-hen in die vorher deklarierte Iterator-Instanz ein. (Beachten Sie bitte die verwendetePunktnotation, die für ORACLE immer verwendet werden sollte.) Die Methode next()wird genauso wie in Beispiel 8.1 für die Abarbeitung der Reihen der Ergebnismengeverwendet.

Die in der Klasse CharVarray deklarierten Methoden ermöglichen das Holen der Infor-mation über den Vektor orte. Die Klasse CharVarray enthält zwei statische Zeichenket-ten mit Informationen zum SQL-Datentypen:

� _SQL_NAME

� _SQL_TYPECODE.

Die Variable _SQL_NAME enthält den Namen, unter dem der Datentyp in der Daten-bank abgelegt wurde, während _SQL_TYPECODE den Typ-Code beinhaltet (d.h. eineeindeutige Identifikationsnummer für jeden unterstützten JDBC-Typ).

Mit Hilfe der length()-Methode wird die Anzahl der im Vektor enthaltenen Elementeermittelt, während die Methode getBaseTypeName() die im Vektor enthaltenen Daten-typen der Elemente als Zeichenkette zurückgibt. (Die verwandte Methode getBase-Type() gibt dieselbe Information als Ganzzahl zurück.)

In der anschließenden do/while-Schleife werden alle Reihen der Ergebnismenge gele-sen. Um einen Schlüssel für die Änderung bestimmter Reihen zu ermitteln, wird dieSpalte firma in die gleichnamige Java-Instanz vom Typ String mit der Anweisung

������!���������24

gelesen. Die Elemente des Vektors werden in die bereits vorher deklarierte Variablearray mit Hilfe der Anweisung

����8�!���������24

gespeichert. Diese Anweisung erstellt eine neue Instanz der Klasse CharVarray undfüllt diese mit den aus der Datenbank gelesenen Werten. Die in dieser Klasse enthal-tene Methode getArray() ermöglicht mit der Anweisung:

����(�56������!�����8�(��"���824

Page 300: Java in Datenbanksystemen

��� ������������ ����� �����������������������

das Auslesen der einzelnen Werte des Vektors in einen Vektor vom Typ String. Es seihier nochmals erwähnt, dass Rückgabetypen, Namen und Parameter jeder Methodeder Klasse CharVarray im erzeugten Quell-Code nachgesehen werden können. Um dieÄnderungen zu demonstrieren, wird in jeder gelesenen Reihe das erste Element desVektors modifiziert und durch den Wert »New York« ersetzt:

����8���$�����2=-�<�E��9=3G4

Da die Änderung zu diesem Zeitpunkt aber nur auf dem Client im Hilfsobjekt arrayausgeführt wurde, wird der geänderte Vektor noch in der Datenbank mit der Anwei-sung:

1����B�"@$������� $@������!�M����8�NK$�$������!�M������D

aktualisiert. Der anschließende Teil des Programms liest erneut alle Reihen aus undgibt diese zur Bestätigung der durchgeführten Änderung am Bildschirm aus.

����( ) *�+��+� �� �,�� �� �-��������

Die Erstellung und Bearbeitung der geschachtelten Tabellen innerhalb eines SQLJ-Pro-gramms wird mit dem folgenden Beispiel veranschaulicht.

Beispiel 8.3

������������ ��������������� ����������������������������������� �������-���.����������������������� �!���������"�#$ ����%%&��'��(���)����&����*����+,�(��������������������������������!��� ����%%�����������������������������������������%%�-���.�/������������-���.+@�&�+$���������1����&������������������/����2������&���3����<��.�������<��.��4 ������&������������.�����2 ����(���(�564���������������2�7��������������&��������2��� 44������� ����������2�2����!���������������������2��� 44�!!���4������� ����������8���������������������%%�������+)��&��.��(9��������*�� :#;�����(�������������������������������������������2��<�������������2���44 ������������ 8��������������2=)��&��.��(�>������?L�=4 ������������%%��������@�&�����.�@8��'�A��

ORACLE

Page 301: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

��������������8�����������������1������B�@"�#$���&������D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D����������������8�����������������1������B�@EB$����<��.�����D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D���������������8�����������������1������B�@EB$���������D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B�@EB$��������D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D������������%%�@�&������.�@8����������������������1�����$"@$�@EB$��������" ���;$�@�2���A����)"��K"�2WG43���������)"��K"�2FG44�D ������������1�����$"@$�@EB$���������" ���;$�@�2�������.�/-@3�����������3����������A���/-@4�D ������������1�����$"@$�@EB$����<��.�����" �@"�#$��0���������D ������������1�����$"@$�@"�#$���&������2��&����/-@3�����������������3����<��.������<��.����3�B�/�"�E�?$E2��&���44�����������������������-$ @$��@"�#$����<��.��� @��$�" �������&��D ������������%%�����������*(��������������1���/- $�@�/-@����&������)"#�$ �2CFWHI3��������2CFW3������2P�����P3PK��P43�WH43�����<��.����2�������2CFH3������2P�����P3P0���>P43�CH43��������2CFI3������2P�����P3P�A������P43�FQ444�D ������������1���/- $�@�/-@����&������)"#�$ �2FWHIC3��������2FWC3������2P �A���.��P3PY���(P43�HR43�����<��.����2�������2FWF3������2P �A��.��P3P������P43�IJ43��������2FWW3������2P���A����P3PK�&���P43�HF444�D ������������1���/- $�@�/-@����&������)"#�$ �2WHICF3��������2WCF3������2PK�&��P3PK�(�P43�JR43�����<��.����2�������2WCW3������2P �A�A����P3P$��9P43�FJ43��������2WCH3������2P���>(��P3P������P43�I[444�D ������������1���/- $�@�/-@��@"�#$2 $#$�@������<��.���0������&�������NK$�$�����&����!�PFWHICP4�)"#�$ �2�������2WCW3������2P �A�A����P3P$��9P43�FJ44�D ������������ 8��������������2=���������(��*(�=4 ������������%%�?�����.��>���$�����(�.���-���.+@�&�+�&��9��M������������%%����&�+���! ��@@%��(���+�!���<��.����������������%%�����������(���A����(�M�-���@���3�B����@���3������������%%����<��.���������������������%%�-���.�/�����������������.��*��������������/������� �����������1�����!� $#$�@�����&���3������<��.���0������&�������D ������������������&���!�WHICF ���������������<��.������< ������������<A��2��������244������������������� 8��������������2=L�#���"�&������=�U������&���24U=M=4 ������������������%%�-$ @$��@"�#$����

Page 302: Java in Datenbanksystemen

��� ������������ ����� �����������������������

�������������������<�!��������<��.��24 ������������������%%�B������+"���8����@�&������������������������B����@56���!��<�(��"���824 ������������������%%�"�(�&��.���@�&���.�������������������������2�����!G ��Z����(�A ��UU4���������������������� 8��������������2�5�6�(��B����/.24U=L�=U�5�6�(��-���24�(��)������24U=L�=U�5�6�(��-���24�(��-��A����24U=L�=U�5�6�(��"���";�A��244 ������������������%%�������&���������)��<��.���+�������>�S�.�����������������������2������&���24�!!���&��4��������������������������2�����!G ��Z����(�A ��UU4����������������������������2�5�6�(��B����/.24����)���24!!WCH4������������������������������ 8��������������2=T�.����)����������B�����WCH�������=4 ����������������������������������%%�*&��������-���@+,�(�������A�.�����������������������������������%%�.���)��������S�.��������������������������������������5�6�(��-���24���)������2=���=4 ������������������������������D����������������������%%�,��*�9�A���&���.��(�S�.������B������+����������������������%%�"���8����.��-���.+@�&���&��9������������������������<���"���82�4 ����������������������%%�T�.����.���-���.+@�&�����.��������&��9����������������������1�����B�"@$���&������ $@����<��.���!�M�<NK$�$���&����!�M��&��D �������������������D������������D������������%%�)�����>������.��������������������������1������!��� $#$�@���&���3����<��.���0������&�����NK$�$���&����!M��&���D ������������<A��2��������244�������������������%%�"�(�&��.���)��<��.���3�(�����<����&�������������������� 8��������������2=L�#���"�&������=�U������&���24U=M=4 �������������������<�!��������<��.��24 ������������������B����@56���!��<�(��"���824 ���������������������2�����!G ��Z����(�A ��UU4���������������������� 8��������������2�5�6�(��B����/.24U=L�=U�5�6�(��-���24�(��)������24U=L�=U�5�6�(��-���24�(��-��A����24U=L�=U�5�6�(��"���";�A��244 ������������D������������%%"&�A���&���������������������������������������������������24 �������������������24 ��������D��������%%"��*A���A��;���+0�A��&�A��.��(M++++++++++++++��������%%��� :#+���A�.���<���������������� :#$��������������������A2 :#$����������4���������������������������A�< :#$��������2�4

Page 303: Java in Datenbanksystemen

������� ����� ���������������������������������� ���

��������D������������A2$����������4������������� 8��������������2=L�+++���&�9�������0�A���+++L�=4 ������������������� ���9@����24 ��������D����D%%$�.����������D

Die Ausgabe des Beispiels 8.3 ist:

)��&��.��(�>������?���������(��*(�#���"�&������CFWHIMCFH�����0���>���������CHCFI������A�������������������FQ#���"�&������FWHICMFWF������������ �A��.���������IJFWW�����K�&��������A������������HFWCW�����$��9���� �A�A�����������FJ#���"�&������WHICFMWCW�����$��9���� �A�A�����������FJWCH���������������>(���I[T�.����)�����������B�����WCH�������#���"�&������WHICFMWCW�����$��9���� �A�A�����������FJWCH����������������>(���I[

Beispiel 8.3 beinhaltet die Anweisungen bezüglich der geschachtelten Tabellen, die inKapitel 2 ausführlich beschrieben sind. (Das Beispiel ist das SQLJ-Äquivalent zu JDBC-Beispiel 5.3.) Da der Aufbau und die verwendeten Methoden ähnlich zu den vorheri-gen beiden Beispielen sind, wird im folgenden nur der Hauptteil des Programmsbeschrieben.

Die Anweisung

1����&������������������/���2������&���3����<��.��������<��.��4

deklariert eine Instanz eines benannten Iterators, die die Spalten arb_nr und verwandteder Tabelle arbeiter (Beispiel 2.13) ausliest. (verwandte ist dabei der Java-Datentyp desObjekttyps namens verwandte_t.) Zur Erzeugung der passenden Java-Klasse kannwieder das in Beispiel 8.1 beschriebene Oracle-Werkzeug Jpublisher verwendet wer-den. Dazu wird folgendes Kommando verwendet:

���&�+���! ��@@%��(���+�!���<��.����

Die Ausführung erzeugt zwei SQLJ- und eine JDBC-Quelldatei – NameT.sqlj, Per-sonT.sqlj und verwandte_t.java –, die in der angegebenen Reihenfolge übersetzt wer-den müssen. Diese drei Klassen sind notwendig, da die Spalte personalien der Tabellearbeiter mit Hilfe des Objekttyps person_t und die Spalte name dieses Typs mit Hilfedes Objekttyps name_t definiert sind.

Page 304: Java in Datenbanksystemen

��� ������������ ����� �����������������������

Mit der SELECT-Anweisung

1������!��� $#$�@���&���3����<��.���0������&������D

werden Werte der Arbeiternummer (als Identifikatoren zum Zurückschreiben) und diegeschachtelte Tabelle selbst gelesen. (Wie bereits erläutert, können mit Hilfe der zweimit den Spaltennamen gleichnamigen Methoden die Werte der jeweiligen Spalte ausder Iterator-Instanz gelesen werden.) Die Methode arb_nr() liest die aktuelle Nummerund die Methode verwandte() die Werte der geschachtelten Tabelle.

Weil die Tabelle verwandte aus lauter Reihen vom Typ person_t besteht, kann man mitder Anweisung:

B����@56���!��<�(��"���824

alle Verwandten eines Arbeiters in einen Vektor namens PersonT einlesen. Die for-Schleife verwendet die in der Klasse PersonT deklarierten Hilfsmethoden, um denInhalt jeder Instanz am Bildschirm auszugeben. In Beispiel 8.3 werden Daten eines Ver-wandten des vorher festgelegten Arbeiters (mit der Nummer 34512) geändert. Mit:

���2�5�6�(��B����/.24����)���24!!WCH4

wird noch überprüft, ob es sich bei dem Verwandten um den von uns gewünschtenhandelt.

Um den Vornamen dieses Vewandten zu ändern, wird dessen Name gelesen und seinVorname auf »Dan« gesetzt:

��5�6�(��-���24���)������2=���=4

(Die Klasse NameT stellt wieder entsprechende Methoden zum Lesen/Schreiben derDaten zur Verfügung.)

Der Vektor mit dem Verwandten (vom Typ PersonT) ist damit aktualisiert. Damit dieÄnderung in der Datenbank gespeichert wird, muss zuerst mit:

�<���"���82�4

der geänderte Vektor in die geschachtelte Tabelle zurückgeschrieben werden. Danachkann mit der UPDATE-Anweisung die geschachtelte Tabelle aktualisiert werden. (Derabschließende Code wiederholt noch einmal einen Teil des beschriebenen Codes, umdie geänderten Daten nochmals auszulesen und anzuzeigen.)

��# ���������� ���� ��� �� ���� �� ���� ��� ��.���-�/

Informix hat folgende Erweiterungen, die in Bezug zur Objektorientierung stehen:

� benutzerdefinierte Datentypen

� Reihentypen

Page 305: Java in Datenbanksystemen

������� ����� ����������������������������"�# �$�% ���

� Kollektionen

� Typ- und Tabellenhierarchien.

Reihentyp und Kollektionen werden im nächsten Abschnitt behandelt, während Typ-und Tabellenhierarchien in einem separaten Abschnitt erläutert werden.

��#�� ' ��� �+ �� !����0�� ���� ��� ��.���-�/

Das folgende Beispiel zeigt die Verwendung der Reihentypen und zwei Kollektionen:Liste und Menge.

Beispiel 8.4

������������ ��������������� ����������������������������������� ����������������� ���/���������������������������������� �!�������/-0���/\ ����%%&��'��(���)����&����*����+,�(��������������������������������!��� ����%%�����������������������������������������%%�-���.�/������������#/ @+$���������1����&������������������/����2 ����(��&�3�"���8#�������������3� ����(�&��A�����4 ������&������������.�����2 ����(���(�564���������������2�7��������������&��������2��� 44������� ����������2�2����!���������������������2��� 44�!!���4������� ����������8���������������������%%�������+)��&��.��(9��������*�� :#;�����(�������������������������������������������2��<�������������2���44 ������������ 8��������������2=)��&��.��(�>������?L�=4 �������������%%��������@�&�����.�@8��'�A����������������8�����������������1������B�@"�#$�&��A�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B���N�@EB$�&��A����$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D

�������

Beispiel 8.4 entspricht dem JDBC-Beispiel 5.4.

Informix

Page 306: Java in Datenbanksystemen

�� ������������ ����� �����������������������

��������������8�����������������1������B���N�@EB$����������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D������������%%�@�&������.�@8����������������������1�����$"@$���N�@EB$���������2������K"�2FG43�������� $@2�K"�2FG4�-�@�-�##4�4�D ������������%%�O�������Y��������������������>���$������.����������&��9����*��.��@8��������(������������ 8��������������2=�������������=4 ������������1�����$"@$���N�@EB$�&��A���2�&���K"�2CW4�-�@�-�##3������������#/ @�2��������-�@�-�##43&��A�������K"�2IG4�4�D ������������ 8��������������2=&��A��������=4 ������������1�����$"@$�@"�#$�&��A��0�@EB$�&��A���2B�/�"�E�?$E2�&�44�D ������������ 8��������������2=&��A������=4 ������������1���/- $�@�/-@��&��A�)"#�$ �2PW+QWFIRR+WW+QP3��������������������=#/ @����N2P������P3� $@�P �����PD43��N2P@��������P3� $@�P0��.����PD43��N2P,��.��P3� $@�P�A������PD4�D=3��������������������P$���A���(�������;���P4����������������D ������������ 8��������������2=C����A�����(��*(�=4 ������������1��/- $�@�/-@��&��A�)"#�$ �2PC+IJIQF+GHI+[P3���������������=#/ @����N2P A���8P3� $@�P;�A�PD43��N2PK�P3 $@�PN��PD43���N2P��(�.P3� $@�P����.PD4�D=3��������������������PY��.�����N�����(���$�"���������P4����������������D ������������ 8��������������2=C����A�����(��*(�=4 ������������1���/- $�@�/-@��&��A�)"#�$ �2PG+H[C+IQQC[+HP3��������������=#/ @����N2P ���P3� $@�P����PD43�����������������N2PY��9��P3� $@�PY���APD43�����������������N2P ���AP3 $@�PB��P3P@�&��PD4�D=3������������������������P���+@�����&����+�������.���.���(P4��������������������D ������������ 8��������������2=C����A�����(��*(�=4 ������������%%�"&���(�����������A�������������/�������3����F ������������1������!��� $#$�@��&�3������������3�&��A�����0����&��A�NK$�$��&���9��PG+]P�D ������������ 8��������������2="&���(����(��*A��L�=4 ������������%%�@8�+���+@�&���������3����.��������>��.����������������������%%�@8�����������?����&>�&�.�������������������������������!�����(��@8�����24 �������������������2=�������=3�������-���2=�������=44 ������������������@8�����2���4 ������������ ����(��&� ������������<A��2��������244�����������������%%� ������&�����M�����������������&��!������&�24 ����������������%%�"���8#����������� ������

Page 307: Java in Datenbanksystemen

������� ����� ����������������������������"�# �$�% ��!

����������������"���8#�������������!�2"���8#��4���������������24 ����������������%%�"��"����������3���.���&������������A�����������������������%%���������.���A�.��@8�������(����������������%%��A���@8�������(�<*�.����������A�����&��9����������������������%%�@8�� ���������A���������������������&����56���������!�������������"���824 ����������������%%�.���&����+"���8���������������+"���8���<��.���+����������������%%������(����9���������A�������A�����������������%%��A���@8��������(�����������A�������� �����56�������������������%%����������.�.������>����A���<����������������������������56����!���<��������5����������(�A6 �������������������2�����!G ��Z����������(�A ��UU4���������������������%%�,�<����(�.���N�������������������+"���8����������������������5�6�!�2�������4��������5�6 ��������������������%%�"�(�&����.��"������3�.���A�.������@8���������������������%%�.������������ ����(+���A�.��������������������� 8��������������2��5�64 ����������������D����������������%%�T�.���������N�����2.���C��"�����<��.�(�S�.���4������������������5G6������!�= �A��.�= ����������������%%�����"�������F�)��������&�9�����M�����������������&����56���<���!���<��&����5F6 ������������������<��5G6�!�=0��.= ����������������%%������)��������.���A������������������A�.��������������������%%������������������������������<��5C6�!���5G6�(��)������2G4 ����������������%%�)��������.���A������������������A�.������������+����������������%%��&��9������>��������������������5G6���)�������2��<��4 ����������������%%�.���"��������������.���(�S�.�����������������������������%%��9�������������������������������������2G3��5G64 ����������������%%�T�.����(�.���"���8�������.������*&����������������������%%�B������. ������������������������B������. ��������������!����������� ��������2=�B�"@$�&��A� $@������������!�^�NK$�$��&���9��P=U�&�U=P=4 ������������������������&����2C3���������4 ���������������� 8��������������2��������������.���24U=����A�2�4�9��������=4 ����������������%%"��������M�2���9����������&������A�4����������������1����B�"@$�&��A� $@�������������!�M���������NK$�$��&���9��M�&��D ����������������%%���������"�(�&��.���(�S�.������N����3�<����&������������������1�����F�!��� $#$�@��&�3������������3&��A������0����&��A�NK$�$��&���9��PG+]P�D �������������������F�����24 ��������������������������!�2"���8#��4����������������24 ������������������������!�������������"���824 �������������������2�����!G ��Z����������(�A ��UU4�

Page 308: Java in Datenbanksystemen

��� ������������ ����� �����������������������

�������������������� 8��������������22�������4�������5�64 ����������������D�������������������F����24 ������������D������������%%"&�A���&���������������������������������������������������24 �������������������24 ��������D��������%%"��*A���A��;���+0�A��&�A��.��(M+++++++++++++��������%%��� :#+���A�.���<���������������� :#$��������������������A2 :#$����������4���������������������������A�< :#$��������2�4 ��������D������������A2$����������4������������� 8��������������2=L�+++���&�9�������0�A���+++L�=4 ������������������� ���9@����24 ��������D����D%%$�.����������D

Ausgabe des Beispiels 8.4 sieht folgendermaßen aus:

)��&��.��(�>������?�������������&��A��������&��A������C����A�����(��*(�C����A�����(��*(�C����A�����(��*(�"&���(����(��*A��-���M� �������������������)�������M���������������������3-���M�Y��9��������������)�������M�Y���A���������������3-���M� ���A����������������)�������M�B������������������3�@�&��3C����A�2�4��9��������-���M� �������������������)�������M���������������������3-���M�Y��9��������������)�������M�Y���A���������������3-���M� ���A����������������)�������M�B������������������3�@�&��3

In Beispiel 8.4 werden zuerst die für SQLJ benötigten Pakete sqlj.runtime.ref.Default-Context und java.sql.* importiert. (Das Paket java.util ist für die später verwendeteKlasse ArrayList nötig.) Die Abfrage des Datenbankeintrags vom Typ LIST übernimmteine Instanz eines benannten Iterators, die folgendermaßen definiert ist:

1����&������������������/����2 ����(��&�3�"���8#�������������3� ����(�&��A�����4

Die Abfrage enthält also zwei alphanumerische Spalten – isbn und buch_titel – sowiedie Spalte autoren_liste, die als Liste deklariert ist. Standardmäßig wird bei Informixder Kollektionstyp LIST auf die Java List-Schnittstelle abgebildet, welcher mit der

Page 309: Java in Datenbanksystemen

������� ����� ����������������������������"�# �$�% ���

Klasse ArrayList implementiert wird. Aus diesem Grund wird in der Iterator-Instanzdieser Typ angegeben.

Nach der schon bekannten Art und Weise werden im Programm die Verbindung mitder Datenbank hergestellt und alle benötigten Tabellen und Reihentypen erstellt. Vor-her werden bereits vorhandene Werte in den try-catch-Blöcken gelöscht. (Dementspre-chend muss bei den DROP-Anweisungen zuerst der speziellste bis hin zumallgemeinsten Typen gelöscht werden, um keine Fehler zu verursachen.)

Bei der INSERT-Anweisung ist in Verbindung mit einer Liste zu beachten, dass vorund nach der Deklaration der Liste ein Anführungszeichen stehen muss, da sonst einSyntaxfehler vom sqlj-Übersetzer erzeugt wird. Um den Reihentypen autor_t aus derDatenbank zu lesen, muss vorher eine äquivalente Java-Klasse erstellt werden. Dies istmit dem Informix-Hilfsprogramm ClassGenerator (enthalten in ifxtools.jar) möglich.Dazu wird folgendes Kommando ausgeführt:

�������Y����������������

Die Vorraussetzung dafür ist, dass das Paket im CLASSPATH eingetragen wird undder Reihentyp autor_t bereits in der Datenbank gespeichert ist.

Nachdem die vorher definierte Iterator-Instanz deklariert wurde, können über eineausführbare Anweisung die Werte geholt werden:

/�������3����F 1������!��� $#$�@��&�3������������3�&��A������0����&��A�NK$�$�&���9��PG+]P�D

Damit der Reihentyp korrekt aus der Ergebnismenge gelesen werden kann, muss demConnection-Objekt die Typabbildung mitgeteilt werden. Dies erfolgt über Instanti-ierung einer Abbildung, in der das Wertepaar <Reihentyp>, <Javatyp> eingetragenwird. Diese Abbildung wird dann dem Connection-Objekt übergeben. Folgender Pro-grammausschnitt führt diese Aufgabe durch:

�����������������������������!�����(��@8�����24 �������������������2=�������=3�������-���2=�������=44 ������������������@8�����2���4

�������

Die Erstellung von Reihentypen und Tabellen kann entweder mit dem Informix-Werkzeug SQLEditor oder einem JDBC- bzw. SQLJ-Programm durchgeführt wer-den, das entsprechende Anweisungen enthält. Auf der CD-ROM befindet sich dieDatei CreateTypesIfx.sqlj mit einem SQLJ-Programm, das alle für Informix benö-tigten Datenbanktypen vorab erstellt.

Page 310: Java in Datenbanksystemen

��� ������������ ����� �����������������������

Zu beachten ist hierbei, dass jeder Kollektionsdatentyp bei Informix einem bestimmtenJava-Datentypen entspricht. Standardmäßig werden ROW in java.sql.Struct, LIST injava.util.ArrayList und SET bzw. MULTISET in java.util.HashSet konvertiert. Überdie gerade gezeigte Methode sind jedoch auch andere Abbildungen möglich.

Die im folgenden Programmteil verwendete und vom ClassGenerator erzeugte Dateiautor_t wurde bereits im Kapitel 5 (siehe Beispiel 5.4) erläutert und wird deshalb hiernicht mehr erklärt. Anzumerken sei hier dennoch, dass genau wie in Beispiel 5.4 füreine bessere Verständlichkeit dem generierten Code einige Methoden hinzugefügtwurden, um die Bearbeitung des Typs zu vereinfachen.

Mit Hilfe der Schleife wird nun jedes Element der Iterator-Instanz durch die next()-Methode ausgewählt und verarbeitet. Die Werte der isbn-Spalte werden als Identifika-toren für die spätere Änderung benötigt. Dafür wird auf die im Iterator vorhandeneisbn()-Methode zurückgegriffen. Mittels

"���8#�������������!�2"���8#��4����������������24

wird die Liste der Autoren gelesen, die ja als LIST definiert wurde. Die Instanzautor_liste enthält nun alle Autoren des gerade verarbeiteten Buches, die enthaltenenElemente entsprechen also autor_t. Da wir die Abbildung des Autor-Typs zu Beginnverändert haben, wird jetzt ein Vektor namens autor_t erstellt, welcher alle Element-werte der autor_liste enthält und entsprechend konvertiert werden muss. In der dazunötigen Schleife wird der Inhalt jedes Autoren mit der toString()-Methode ausgege-ben. Die Methode toString() stellt eine eigene Erweiterung der erzeugten autor_t-Klasse dar. Sie wurde bereits in Kapitel 5 ausführlich besprochen.

Im folgenden Programmabschnitt können über die in autor_t definierten Methodendie Daten eines jeden Autoren gelesen und geschrieben werden. Zur Änderung desVornamens werden alle Vornamen des Autors gelesen, dann wird einer davon geän-dert und der Object-Vektor wieder mit Hilfe der Methode setVornamen() zurückge-schrieben. Dabei wird die in autor_t enthaltene Array-Instanz ersetzt. Die geändertenDaten eines Autors werden dann in die autor_liste mit der set()-Methode der KlasseArrayList zurückgeschrieben.

Üblicherweise müsste eine Änderung der Datenbank über folgende Anweisung funk-tionieren:

1����B�"@$�&��A� $@�������������!�M����������NK$�$��&���9�M�&��D

Die obige Änderung wird von Informix nicht unterstützt. Damit die Änderung derDaten im Programm gezeigt wird, haben wir eine Instanz der PreparedStatement-Klasse verwendet, in die die ArrayListe über die setObject()-Methode eingetragenwird.

Page 311: Java in Datenbanksystemen

������� ����� ����������������������������"�# �$�% ���

Eine weitere Iterator-Instanz liest nun die veränderten Daten nochmals aus und stelltsie am Bildschirm zur Überprüfung dar.

��#�# .���-�/�, !+� ����+� �

Die Erstellung und Bearbeitung der hierarchischen Tabellen sowie die Ausgabe undÄnderung eines STRUCT-Typs innerhalb eines JDBC-Programms wird mit dem folgen-den Beispiel veranschaulicht.

Beispiel 8.5

������������ ��������������� ����������������������������������� ����������������� ���/����8�A����������������������� �!�������/-0���/\ ����%%&��'��(���)����&����*����+,�(��������������������������������!��� ����%%�����������������������������������������%%�-���.�/������������#/ @+$���������1����&������������������/����2�������������4 ������&������������.�����2 ����(���(�564���������������2�7��������������&��������2��� 44������� ����������2�2����!���������������������2��� 44�!!���4������� ����������8���������������������%%�������+)��&��.��(9��������*�� :#;�����(�������������������������������������������2��<��������������������������2���44 ������������ 8��������������2=)��&��.��(�>������?L�=4 ������������%%��������@�&�����.�@8��'�A����������������8�����������������1������B�@"�#$������A����D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B���N�@EB$�9�����������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B���N�@EB$����������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�

�������

Beispiel 8.5 entspricht dem JDBC-Programm in Beispiel 5.5.

Informix

Page 312: Java in Datenbanksystemen

��� ������������ ����� �����������������������

����������������1������B���N�@EB$����������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B���N�@EB$��.�������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D��������������8�����������������1������B���N�@EB$���������$ @�/�@�D ������������D����A2 :#$����������4�������A�< :#$��������2�4 D������������%%�@�&������.�@8����������������������1�����$"@$���N�@EB$�������2���A������K"�2FG4�-�@�-�##3����������������������K"�2FG44�D ������������1�����$"@$���N�@EB$��.������2��.���K"�2FI4�-�@�������������-�##3������K"�2FG4�-�@�-�##3A�����/-@$Y$��-�@�-�##4�D ������������1�����$"@$���N�@EB$���������2��������3������������3��������������.�����.�����3�����������/-@$Y$�4�D ������������1�����$"@$���N�@EB$���������2����������/-@$Y$��-�@�������������-�##3��������������K"�2FI4�-�@�-�##3��.�����.�����4�D ������������1�����$"@$���N�@EB$�9����������2�������������������������3���9������K"�2FG44��-�$����������D ������������ 8��������������2=@8���������=4 ������������1�����$"@$�@"�#$������A�����0�@EB$�9����������������������2B�/�"�E�?$E�2����44�D ������������ 8��������������2=@�&��������=4 ������������1���/- $�@�/-@�������A����2����3�����3��.���3����������������������3������3����9����4���������������)"#�$ �2RIQ3�" @2���N2�P�����P3�PK��P4�" ��������43����������������" @2���N2P ����&��(P3�P0�.<�(P3�[4�" ��.������43���������������GRQJI[HR3��" @2���N2CF3�P��NP3��" @2���N2P�*��A��P3����������������PK�������_�P3�CJ4�" ��.�����44����������������" ���������4��3�P�����&�����P4�D ������������ 8��������������2=���A�����(��*(�=4 ������������1���/- $�@�/-@�������A����2����3�����3��.���3����������������������3������3����9����4��������������)"#�$ �2RJG3�" @2���N2�PY��&��P3�PB����P4�" �������43����������������" @2���N2P"�����(P3�P���A�����_�P3�W4�" ��.�����43���������������GCJG[W[JRIW3��" @�2���N2WH3�P"�.�P3��" @2�����������������N2P/�(���.�P3�P/�.��������_�P3�IJ4�" ��.�����44���������������" ���������43�P$��<��9��P4�D ������������ 8��������������2=���A�����(��*(�=4 ������������1���/- $�@�/-@�������A����2����3�����3��.���3����������������������3������3����9����4��������������)"#�$ �2RJC3��" @2���N2�P �A��.�P3�P0���.���AP4��" ��������������������43�" @2���N2P ����(���P3�P��A�A�����_�P3�CW4��������������" ��.�����4�3�GC[C[H[JHRF3��" @2���N2FW3�P���P3���������������" @2���N2P�*�A���P3�P#��.�����_�P3�R4�" ��.�����44��������������" ���������43�P/�(������P4�D ������������ 8��������������2=���A�����(��*(�=4 ������������%%�"&���(�����������A�������������/������� ������������1������!��� $#$�@�������0���������A����D ������������ 8��������������2="&���(����(��*A��L�=4

Page 313: Java in Datenbanksystemen

������� ����� ����������������������������"�# �$�% ���

������������%%�@8�+���+@�&���������3����.��������>��.����������������������%%�@8�����������?����&>�&�.�������������������������������!�����(��@8�����24 �������������������2=�������=3�������-���2=�������=44 ������������������@8�����2���4 �������������������������� ������������<A��2��������244�����������������%%�0�����������.����;���+�&��9��9���������������������������������!�2�������4���������24 ����������������%%�0�����.�������(�&���*&������������� ����(24+����������������%%����A�.����������������� 8��������������2=L�=U�����4 ���������������� 8��������������2=L�T�.���� ��.�����-�<�E��9=4 ����������������%%��.�����+ �����������A�&�0�����*&������A�.�����������������%%��� ��.�24�S�.��������������������������� ��.�2=-�<�E��9=4 ����������������������!�������������� ����������������%%�T�.����(�.���"���8�������.���������� :#;����������������1����B�"@$������A���� $@�������!�M������NK$�$���������������������������������!�M���D ������������D������������%%�������A������A����������T�.����(�>��&��S��(��M������������ 8��������������2=L������A���������&��9M=4 ������������1������!��� $#$�@�������0���������A����D ������������<A��2��������244����������������� 8��������������22�������4���������244 ������������D������������%%"&�A���&��������������������������������������������������24 �������������������24 ��������D��������%%"��*A���A��;���+0�A��&�A��.��(M+++++++++++++��������%%��� :#+���A�.���<���������������� :#$��������������������A2 :#$����������4���������������������������A�< :#$��������2�4 ��������D������������A2$����������4������������� 8��������������2=L�+++���&�9�������0�A���+++L�=4 ������������������� ���9@����24 ��������D����D%%$�.����������D

Die Ausgabe des Beispiels 8.5 sieht folgendermaßen aus:

@8���������@�&�����������A�����(��*(����A�����(��*(����A�����(��*(�

Page 314: Java in Datenbanksystemen

��� ������������ ����� �����������������������

"&���(����(��*A��0�����+1M�CF�0���������M���N���.���������*��A��������������������3�K�������_����������3�CJ3�DT�.���� ��.�����-�<�E��90�����+1M�WH�0���������M�"�.���.��������/�(���.����������������3�/�.��������_������3�IJ3�DT�.���� ��.�����-�<�E��90�����+1M�FW�0���������M������.���������*�A�����������������3�#��.�����_���������3�R3�DT�.���� ��.�����-�<�E��9�����A���������&��9M0�����+1M�CF�0���������M���N���.��������-�<�E��9�����������������3�K�������_����������3�CJ3�D0�����+1M�WH�0���������M�"�.���.��������-�<�E��9�����������������3�/�.��������_������3�IJ3�D0�����+1M�FW�0���������M������.��������-�<�E��9�����������������3�#��.�����_���������3�R3�D

Am Anfang des Beispiels 8.5 werden die Pakete sqlj.runtime.ref.DefaultContext undjava.sql mit Hilfe der import-Anweisung in das Programm eingebunden. Die für dieAbfrage benötigte Iterator-Instanz liest die Werte des in der Datenbank gespeichertenReihentyps firma_t und deklariert seine einzige Spalte daher als vom Typ firma_t. Die-ser Typ ist die Java-Implementierung des Datenbanktyps, die leider selbst implemen-tiert werden muss, da der ClassGenerator diesen Typ (noch) nicht unterstützt. Wiedies konkret aussieht, kann in Kapitel 5 (siehe Beispiel 5.5) nachgesehen werden, dadort das gleiche Objekt verwendet wird.

Nach der schon bekannten Art und Weise werden im Programm die Verbindung mitder Datenbank hergestellt und alle benötigten Tabellen und Reihentypen erstellt. Vor-her werden bereits vorhandene Typen in den try-catch-Blöcken gelöscht. (Dementspre-chend muss bei den DROP-Anweisungen zuerst der speziellste bis hin zumallgemeinsten Typ gelöscht werden, um keine Fehler zu verursachen.)

Beim Einfügen von benannten Reihentypen mit SQLJ ist zu beachten, dass hier derCAST-Operator (»::«) nicht verwendet werden darf. Stattdessen muss die CAST AS-Angabe benutzt werden. Folgende Programmzeile also:

/- $�@�/-@�������A����2����4�)"#�$ �2��N2�P�����P3�PK��P4MM������4

muss durch folgende äquivalente Anweisung ersetzt werden:

/- $�@�/-@�������A���2����4�)"#�$ 2�" @2��N2P�����P3PK��P4�" �������4

Eine Instanz des benannten Iterators erhält über die SELECT-Anweisung alle Elementedes Reihentyps firma_t. Da es sich hierbei wieder um einen Kollektionstyp handelt,benötigen wir wieder eine Typabbildung auf ein Java-Objekt, um die enthaltenenDaten zu lesen und zu ändern.

Page 315: Java in Datenbanksystemen

&'�$$��#�''�� ���

Mit Hilfe von

�����������������������������!�����(��@8�����24 �������������������2=�������=3�������-���2=�������=44 ������������������@8�����2���4

wird die Umwandlung des Reihentyps firma_t in das Java-Objekt firma_t durchge-führt. In der Schleife werden alle Elemente verarbeitet und mit Hilfe der next()-Methode ihre Daten ausgegeben. Dazu wird die im Iterator vorhandene Methodefirma() benutzt, welche ein Objekt vom Typ firma_t zurückliefert. Dessen Inhalt wirdüber println() ausgegeben, dabei wird die in firma_t deklarierte toString()-Methodeautomatisch aufgerufen. Über die ebenfalls dort deklarierte Methode setStadt() kannnun dieser Eintrag geändert werden.

Für die Änderung des Objektes wird die Firmennummer benötigt, die vom Typ int ist.In der UPDATE-Anweisung werden die Host-Variablen nr und firma übergeben, umdas geänderte Java-Objekt in die Datenbank zurückzuschreiben.

Am Programmende werden noch einmal alle geänderten Reihen ausgegeben, um dieÄnderung visuell zu bestätigen.

��( ��*�-- ���**���

Die in diesem Buch betrachteten Datenbanksysteme Oracle, Informix und DB2 unter-stützen in ihren SQLJ-Implementierungen objektorientierte Erweiterungen in verschie-denem Umfang.

Ein wichtiges Mittel bei Oracle für die Erstellung von SQLJ-Programmen mit objekt-orientierten Erweiterungen ist Jpublisher. Dieses Werkzeug ermöglicht die Erstellungneuer Java-Datentypen, die die Datentypen wie REF, VARRAY usw. in einem SQLJ-Programm darstellen.

Informix unterstützt ein Werkzeug namens ClassGenerator, das große Ähnlichkeitenmit Jpublisher hat. Ein Nachteil ist, dass die Änderungen mit Hilfe der UPDATE-Anweisung (noch) nicht unterstützt werden, was die Programmierung solcher Funk-tion komplexer macht.

Die Firma IBM hat die im DB2-Server unterstützten objektorientierten Erweiterungennoch nicht in SQLJ implementiert.

Das nächste Kapitel beschreibt einige Fälle, die die Performance von SQLJ unter-suchen. Es ist gleichzeitig das letzte Kapitel, das sich mit SQLJ befasst.

Page 316: Java in Datenbanksystemen
Page 317: Java in Datenbanksystemen

� ����������� ��������������

In diesem Kapitel werden wir einige Beispiele zeigen, wie der Benutzer seine SQLJ-Anwendungen performanter gestalten kann. Einige dieser Beispiele sind systemneu-tral, während andere sich auf das spezifische Datenbanksystem beziehen. Das Kapitelist in Abschnitte unterteilt, von denen jeder einen Performance-Fall diskutiert.

Auf eine Einleitung in Bezug auf die Performance allgemein wird in diesem Kapitelverzichtet. Die ist in Kapitel 6 gegeben, das ein Analogon zu diesem Kapitel darstellt(mit dem Unterschied, dass in Kapitel 6 die Performance von JDBC untersucht wird).Genauso ist das in Kapitel 6 dargestellte Verfahren für die Durchführung von Perfor-mance-Tests (siehe Abschnitt 6.2) auch für die Performance-Tests mit SQLJ gültig.

��� ����������������������������������

Das Ergebnis der in Abschnitt 6.3 vorgestellten Vorgehensweise zur Optimierung derDatenbankzugriffe mit JDBC zeigt, dass es in solchen Fällen immer wesentlich besserist, die Ergebnismenge einmal festzulegen und dann mit dem Iterator die Reihen zulesen, als für jede Reihe einmal die entsprechende SQL-Anweisung (meistens SELECT)auszuführen. Der Vorteil der ersten Programmierungsart ist, dass eine wesentlichgeringere Anzahl von E/A-Operationen notwendig ist.

Beispiel 9.1 zeigt ein SQLJ-Programm, das Reihen aus der Tabelle mitarbeiter auf einenicht performante Art und Weise liest, d.h. jede Reihe wird mit einer SELECT-Anwei-sung gelesen.

Beispiel 9.1

���������������� ������������������������

�������������������� �!"#��$!% � &'

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04���

5

��������0��,��� &$��6� &2�,�*������.

Page 318: Java in Datenbanksystemen

��� ����������� �������������������

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

�������&�����!������09������=���,,��$��������

����@�+,�(/�,���������������$����!��A���4� ����8��4���

��������8��4������ ����8���4�B.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������0���A��)6>.�)J���3��2"=K>.�)KKB

������������5����������������

���������������F���*�/*(��,AG /���,�/0����G�K�)�B.

����������������#9��)������;�������0��8������;��6�L???���0��8�

��������������0���A���6>???.��J�LLLL.��KKB

��������������5

����������������������!��������������

��������������������$����!��������4���.

��������������������@�+,������4���65�����=�-�0�������������

���������������������<M�����4�6��N.

���������������������0A�����4���*�1ABB

���������������������F���*�/*(��,AG$4"���G�K

��������������������������4���*�4�ABB.

�������������������������4���*�,���AB.

������������N

���������������F���*�/*(��,AG &�:/8��00���/����,�/

����������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

���������������O��4���B�K�G���,,����/��GB.

�������������������,/��������---------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

��������F���*�/*(��,AGI��2�������#��,�����8������IGB.

�������������*(������=����AB.

Page 319: Java in Datenbanksystemen

������������� ���������� �� � ����� ���

��������N

����N���������$��

N

In Beispiel 9.1 wurde einer Instanz eines Iterators innerhalb einer for-Schleife eineSELECT-Anweisung zugewiesen. Aus diesem Grund wird die Abfrage jedesmal neuübersetzt und danach ausgeführt.

Beispiel 9.2 zeigt die effiziente Art, das in Beispiel 6.1 dargestellte Problem zu lösen.

Beispiel 9.2

���������������� ��������������������

�������������������� �!"#��$!% � &'

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04��

5

���������0��,��� &$��6� &2�,�* &'.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

�������&�����!������09������=���,,��$��������

����@�+,�(/�,���������������$����!��A���4� ����8��4���

���8��4������ ����8���4�B.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������0���A��)6>.�)J���3��2"=K>.�)KKB

������������5����������������

�������������������!���������;�����

����������������$����!��������4���.

������������������F���*�/*(��,AG /���,�/0����G�K�)�B.

���������������������>���0��8��09��L???��P;������;�

����������������@�+,������4���6�5�����=�-�0��������������<M���

������������������4��&�=<��"�>???��" �LLLLN.

���������������������8������8�����������

�������������������,��A������4���*�1AB�B

Page 320: Java in Datenbanksystemen

�!" ����������� �������������������

�������������������������F���*�/*(��,AG$4"���G�K

������������������������������4���*�4�ABB.

���������������������4���*�,���AB.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������---------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�����������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

Die wichtigste Eigenschaft des Beispiels 9.2 ist, dass die SELECT-Anweisung sichaußerhalb der while-Schleife befindet und deswegen nur einmal vorbereitet wird.Damit wird die Ergebnismenge erstellt, die dann in einer while-Schleife mit der next()-Methode so oft verarbeitet wird, wie die Anzahl der Reihen der Ergebnismengebeträgt.

Tabelle 9.1 zeigt die Messergebnisse.

�� !"��#�� ��!����������$�������#�� ����

��� ���"�

Bei Oracle kann ein PL/SQL-Block innerhalb der geschweiften Klammern einer aus-führbaren SQLJ-Anweisung genauso erscheinen, wie jede einzelne Anweisung. (PL/SQL ist die prozedurale Erweiterung der SQL-Sprache bei Oracle, die zur Programmie-rung von gespeicherten Prozeduren dient.) Folgende SQLJ-Anweisung zeigt das:

%����� ��������������������������$��&��� ���� '()'*�+ +�,�����

%����� ���������������������"�$��&��� ��������

������#�����#������� �&-��

(() .��(��,����

#���$$���%�&���������� ���������� �� � �����&�����'���$���(

Page 321: Java in Datenbanksystemen

)$��*�����)�������� ��+ ������ *���� �� ���� ����$� �!�

@�+,�5&�Q!"

������!"���=�!"=���������������2��A'R �S$����T �SM��T �S�>TB.

������!"���=�!"=���������������2��A'U �SM/���T �S�����T �S�RTB.

������!"���=�!"=���������������2��A'R �S��,;T �S�����T �S�'TB.

�������" .

�����N.

Das Zusammenfügen mehrerer SQL-Anweisungen in einen (so genannten anonymen)Block ist performanter als jede SQL-Anweisung einzeln zu implementieren, weildadurch der Netzverkehr verringert wird und die gruppenweise Übersetzung derAnweisungen schneller als die Übersetzung jeder einzelnen ist.

Beispiel 9.3 zeigt die Programmierung ohne einen anonymen Block.

Beispiel 9.3

�����;�, �����8��,������098� �����

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����"�4��F�

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������0���A���6?.��J���3��2"=.��KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K��B.

��������������������V??�$�����������098�

�������

Die Verwendung von anonymen PL/SQL-Blöcken bei Oracle ist in seiner Funk-tionsweise mit der Methode executeBatch() von JDBC vergleichbar.

Page 322: Java in Datenbanksystemen

�!! ����������� �������������������

����������������0���A��)6>????.)J>?V??.�)KKB

��������������������@�+,�5�!"���=�!"=�����������

������������������������2��A�) T,�8T T��T T�RTBN.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������--------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8���������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

In Beispiel 9.3 werden innerhalb einer for-Schleife maximal 500 INSERT-Anweisungenausgeführt, wobei jede von ihnen als separate Anweisung betrachtet wird.

Beispiel 9.4 zeigt die Verwendung eines anonymen Blocks bei Oracle.

Beispiel 9.4

��������/8�����,����F����3������&,��� �����

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,������F�

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

Page 323: Java in Datenbanksystemen

)$��*�����)�������� ��+ ������ *���� �� ���� ����$� �!�

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������0���A��)6?.�)J���3��2"=.�)KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K�)B.

��������������V??�$�����������098�����,����F���(,��+,�&,���

����������������@�+,

����������������5

�������������������� �����������8��.

��������������������&�Q!"

�����������������������������6>???>.

������������������������������3

������������������������������!"���=�!"=�����������

����������������������������������2��A� T,�8T T��T T�RTB.

�������������������������������%!=�<M�"��6>?V??.

��������������������������������6�K>.

����������������������������" ����3.

���������������������" .

����������������N.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������-------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8���������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

Tabelle 9.2 zeigt die Messergebnisse.

%��&���$��'((��/�����-����0�����1����2�!"�� (()34�'((�,����

%��&���$��'((��/���������������0�����1����!"��� (()�*�3+3�,�����

#���$$���%!&�'��*� �� ���� ���� ,�� ���-����)$�����������$�

Page 324: Java in Datenbanksystemen

�!. ����������� �������������������

��* 5��#������� ������0� �6%7��������"�

In Oracle hat jede Reiheninstanz einen Identifikator (object identifier), mit dem sie ein-deutig identifiziert wird. Dieser Identifikator kann verwendet werden, um einer Spalteeiner Tabelle eine ganze Instanz einer anderen Tabelle zuzuweisen. Dafür steht derREF-Datentyp zur Verfügung. Ein Anwendungsbereich des REF-Datentyps ist dieErsetzung der (nicht effizienten) Join-Operationen. Diese Problematik ist in Kapitel 2im Abschnitt »Ersetzung der Join-Operation mit Hilfe des REF-Datentyps« beschrie-ben.

Auf der Basis des oben genannten Abschnitts haben wir die Performance zweier SQLJ-Programme getestet. Das eine Programm verwendet die Join-Operationen, um Tabel-len miteinander zu verknüpfen, während das andere dasselbe Problem mit Hilfe desREF-Datentyps löst (siehe auch Beispiele 2.24 und 2.25).

Beispiel 9.5 zeigt die Verwendung der »üblichen« Join-Operation, um die Verknüpfungdreier Tabellen der Beispieldatenbank (arbeiten, mitarbeiter, projekt) zu implementie-ren.

Beispiel 9.5

������9(0/8����=���,,�������!" �����

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04)��

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

�������������!������09�����������/8

����@�+,�(/�,������������������!��A���8��/08��� ����8

������4��� ����8�(�4���B.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

����������������0�8�;��(/��09��:������/8

Page 325: Java in Datenbanksystemen

'��*� �� ���������� �,���/01���������$� �!2

������������,�8��4����6��F���*�/���=���$�,,��AB.

���������������!������!��.

������������0���A���6?.��J���3��2"=.��KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K��B.

�����������������������,,���������0���;��/0�����=���,,�

�����������������$���������/��3��)�� ����,����!"

�����������������������;/�����;�

����������������@�+,����!���6�5

�����������������������������=�������*�/08��� ����������*�4���

�������������������������(��)��*(�4���

������������������������#��$���������� ������� �(��)��

������������������������<M�������������*�4��6�������*�4�

�������������������������" �������*(�4��6�(��)��*(�4�

�������������������������" ����4���W�T?>*?>*>LXXT

����������������N.

����������������@�+,�5���$$!=�N.

�������������������!��*�,���AB.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������-----------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�����������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

In Beispiel 9.5 wurde einer Iterator-Instanz die SELECT-Anweisung, die zwei Join-Operationen enthält, zugewiesen.

Beispiel 9.6 löst das in Beispiel 9.5 implementierte Problem mit Hilfe des REF-Daten-typs.

�������

Um aussagekräftige Ergebnisse zu erzielen, haben wir die Anzahl der Reihen derTabellen arbeiten, mitarbeiter und projekt bei den Tests signifikant erhöht. In dieTabelle arbeiten wurden vor dem Test 6000 Reihen, in die Tabelle mitarbeiter 3000Reihen und in projekt 1000 Reihen geladen.

Page 326: Java in Datenbanksystemen

�!3 ����������� �������������������

Beispiel 9.6

�������9(0/8�����(�,�������# �����

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04��0

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

�������������!������09�����������/8

����@�+,�(/�,������������������!��A���8� ����8 ����8B.

������-------------------------------------

(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

����������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

���������������!������!��.

������������0���A���6?.��J���3��2"=.��KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K��B.

�����������������������,,���������0���;��/0�����=���,,�

�����������������$���������/��3��)�� �/����������;/�����;�

����������������@�+,

����������������5

������������������������=��=Y3��������4�����&���=�A�4��!"=

���������������������(�4���M��AUB ��/08�����M��A'VB ����4��� �=�

������������������������4�����#���������� ����4(�����0�(��)��.

������������������������=��=�&���������>��#�������4.

����������������N.

����������������������9(0/8�9������������=���,,������,0�������#

����������������@�+,����!���6�5������=��*�/08��� ��*���4��*�4���

������������������*���4(��*(�4����#��$

����������������������������������������������>������������4���W�T?>*?>*>LXXT�

N.

�������������������!��*�,���AB.

������������N

���������������F���*�/*(��,AG &�:/8��00���/����,�/

Page 327: Java in Datenbanksystemen

'��*� �� ���������� �,���/01���������$� �!4

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

��������������O��4���B�K�G���,,����/��GB.

�������������������,/��������-----------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

In Beispiel 9.6 wird zuerst ein Objekttyp arbeiten_t erstellt, der im Unterschied zur inKapitel 1 definierten Tabelle arbeiten zwei zusätzliche Spalten – arb_mit und arb_pro –enthält, die für die Referenzierung je einer Reihe der Tabellen mitarbeiter1 und projekt1(in dieser Reihenfolge) dienen. Damit enthält die mit der Iterator-Instanz arbIter verbun-dene SELECT-Anweisung nur den Bezug auf eine einzige Tabelle arbeiten1.

Aufgrund der Tests, die wir ausgeführt haben, kann man sagen, dass der REF-Opera-tor um ein vielfaches schneller ist als eine Join-Operation, wenn keine Indizes auf Pri-mär- und Fremdschlüssel erstellt wurden. Bei der Indizierung der Spalte, die in derWHERE-Klausel den Filter bildet (einst_dat), sind die Operatoren etwa gleich perfor-mant. Werden aber die Primärschlüssel der Tabellen mitarbeiter, arbeiten und projektindiziert, so ist die Verwendung der Join-Operation performanter als die Benutzungdes REF-Datentyps.

Tabelle 9.3 zeigt die Testergebnisse.

%� ������� ������������� �&����*�8���""�������" �6%7��#�� �� (()( �4'4�,����

5��#������ ������������� �&����*�8���""� ��)�'�+�(�,�����

5��#������ ������������� �&����*�8���""�����������9��:�

��������7�"��� ��"���;�� �<���=

(()( �* +�,�����

5��#������ ������������� �&����*�8���""������9���� �

������������/� -"& �"�����8���""�

(()(��4'4�,�����

#���$$���%�&�#��������������� �������� �� ������/01����� �,�

Page 328: Java in Datenbanksystemen

�!� ����������� �������������������

��3 �� �&-���$�������#�� ����$ ���� ���-�����

���������

Wie wir in Kapitel 1 erläutert haben, haben gespeicherte Prozeduren mehrere Vorteileim Vergleich zu der Ausführung derselben Anweisungen (einzeln oder gruppenweise)auf der Client-Seite. Diese Vorteile sind:

� die wiederholte Übersetzung einer gespeicherten Prozedur wird durch das Spei-chern auf der Server-Seite (in den meisten Fällen) eliminiert,

� die Anzahl der Zugriffe zwischen dem Client und dem Server wird reduziert, weileine Prozedur auf der Server-Seite gespeichert ist.

Folgende zwei Beispiele lösen dasselbe Problem: das Einfügen von 3000 Mitarbeiternin die Beispieldatenbank und das anschließende Ändern von Mitarbeiternamen. Bei-spiel 9.7 verwendet keine gespeicherten Prozeduren, um das oben dargestellte Pro-blem zu lösen.

Beispiel 9.7

��������/8��������������������������'

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04�������'

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

�������

Weil die Implementierung der gespeicherten Prozeduren herstellerspezifisch ist,werden wir in diesem Abschnitt die PL/SQL-Sprache von Oracle wählen. (Die Per-formance-Vorteile werden auch bei der Verwendung der gespeicherten Prozedurenbei den anderen Herstellern ähnlich sein.)

Page 329: Java in Datenbanksystemen

���5(�� �+ ������ *���� �� �+�%��������(������� ����� �!�

��������������*���/������A0�,��B.

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������0���A��)6?.�)J���3��2"=.�)KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K�)B.

����������������@�+,�5���$$!=�N.

�������������������R???�$�����������098�

����������������0���A���6>????.��J>R???.��KKB

����������������5

��������������������@�+,�5

������������������������!"���=�!"=���������������2���A��

�������������������������T$���T �T����00��T T�RTBN.

����������������N

����������������@�+,�5���$$!=�N.

����������������0���A���6>R???.��J>Z???.��KKB

����������������5

��������������������@�+,�5

������������������������23 �=��������������=��4��6����<M�����4�6

�����������������������������R???N.

����������������N

����������������@�+,�5���$$!=�N.

����������������@�+,�5� ���=��#��$�����������<M�����4��W�>'LLL

���������������������4��J�>Z??>N.

����������������@�+,�5���$$!=�N.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������-------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

Beispiel 9.8 verwendet die PL/SQL-Sprache, um das Einfügen von 3000 Mitarbeiternin die Tabelle mitarbeiter durchzuführen und die Mitarbeiternamen zu ändern.

Page 330: Java in Datenbanksystemen

��" ����������� �������������������

Beispiel 9.8

��������3�����/����/�09��� ���������;/�3��04�������'

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(���2�,�*-.

�,����3��04(�����/��'

5

��������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

�������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>?.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

�������0A�E &2�,�*�� ������ �����A &$�BB���/�.

��������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

��������������*���/������A0�,��B.

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

������������@�+,�5

�������������������=�������3�����3���� 2����������'���

���������������.

������������&�Q!"

��������������#�����!"�>????**>R??>����3

���������������!"���=�!"=���������������2���A�

����������������T���T T�����T T�RTB.

���������������" ����3.

��������������#�����!"�>R???**>Z???����3

���������������23 �=��������������=��4��6����������4�6��R???.

���������������" ����3.

�������������� ���=��#��$�����������<M�����4��W�>'LLL�����4��J

���������������>Z??>.

�������������" .

��������������N.

�������������0�8�;��(/��09��:������/8

����������,�8��4����6��F���*�/���=���$�,,��AB.

����������0���A��)6?.�)J���3��2"=.�)KKB

����������5

��������������F���*�/*(��,AG /���,�/0�"���G�K�)B.

��������������@�+,�5���$$!=�N.

�����������������3��;��/�����!��� �2(����/�� �,�������/8��

��������������@�+,�5�������������'AB�N.

������������@�+,�5���$$!=�N.

Page 331: Java in Datenbanksystemen

/*�������(� ����������$� ���

����������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

�������������O��4���B�K�G���,,����/��GB.

�������������������,/��������--------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�����������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

���������F���*�/*(��,AGI�2�������#��,�����8������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

Die gespeicherte Prozedur commands2 enthält neben dem Einfügen von 3000 Mitar-beitern auch 3000 UPDATE-Anweisungen, bei denen die Mitarbeiternummern um denWert 3000 inkrementiert werden. Anschließend werden die aktualisierten Mitarbeiterwieder gelöscht.

Tabelle 9.4 zeigt den Performance-Vorteil der gespeicherten Prozedur.

��' 6�#�������-����������"�

Bei einer Abfrage werden standardmäßig einzelne Reihen der Ergebnismenge vomServer an den Client geschickt. Weil dieses Verfahren nicht performant ist, unterstütztdas Oracle-System das sogenante row prefetching. Mit diesem Verfahren wird ein (pre-fetch) Wert spezifiziert, der die Anzahl der Reihen, die in einem Durchgang vom Clientempfangen werden, festlegt. Die entsprechende Methode heißt setDefaultRowPre-fetch(), die zu Klasse OracleConnection gehört. (Um diese Methode verwenden zukönnen, muss ggf. der Kontext in eine Instanz der Klasse OracleConnection konver-tiert werden.)

Beispiel 9.9 zeigt ein SQLJ-Programm, das kein row prefetching anwendet.

�������������������#�� �� ������ ( )3��+ +�,����

9���� -���� ���-������������� (�)'3�(*��,����

#���$$���%.&�6������(������� ����� �� ��� *���� ��������&�����'���$���(

Page 332: Java in Datenbanksystemen

��! ����������� �������������������

Beispiel 9.9

���H�������3��0�����������

��������������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(�������,�*)���*������*����,�������.

��(���2�,�*-.

�,����3��04�4���4(��0���

5

���������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

��������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>??.

�������&�����!������09������=���,,��$��������

����@�+,�(/�,���������������$����!��A���4� ����8��4���

��������8��4������ ����8���4�B.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

���������0A�E &2�,�*�� ������ �����A &$�BB���/�.

���������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

���������������0�8�;��(/��09��:������/8

������������,�8��4����6��F���*�/���=���$�,,��AB.

������������$����!���!���6�/,,.

����������������/6?.

������������0���A��)6?.�)J���3��2"=.�)KKB

������������5

�����������������F���*�/*(��,AG /���,�/0�"���G�K�)B.

����������������@�+,�!���6�5������=�-�#��$�����������N.

�������������������,��A!��*�1ABB

����������������������������������/KK.

����������������!��*�,���AB.

������������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

����������������4���B�K�G���,,����/��GB.

�������������������,/��������------------------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8����������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

Page 333: Java in Datenbanksystemen

/*�������(� ����������$� ���

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

����F���*�/*(��,AGI����2�������#��,�����8��������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

In Beispiel 9.9 wird eine SELECT-Anweisung ausgeführt, die alle Reihen der Tabellemitarbeiter liest. Mit einer while-Schleife wird anschließend der Wert eines Zählers beijedem Durchgang um eins erhöht. (Um das Performance-Verhalten der setDefault-RowPrefetch()-Methode wahrheitsgemäß untersuchen zu können, wurde die Tabellemitarbeiter mit 5000 Reihen geladen.)

Beispiel 9.10 verwendet das row prefetching-Verfahren.

Beispiel 9.10

�������3��0�����������

�������������

��(���)���*�+,*-.

��(����+,)*�/���*-.

��(����+,)*�/���*��0* �0�/,���1.

��(�������,�*)���*������*����,�������.

��(���2�,�*-.

�,����3��04���4(��0���

5

��������0��,��� &$��6� &2�,�*������.

��������7�8��������,��09�� &�:/8��00---

�������������������6�/,,.

�������;��,�����<�������,/8�

���������0��,�����3��2"=�6�>??.

�������&�����!������09������=���,,��$��������

����@�+,�(/�,���������������$����!��A���4� ����8��4���

��������8��4������ ����8���4�B.

������-------------------------------------

����(/�,����������������A���8���8�CDB

����5

�������0A�E &2�,�*�� ������ �����A &$�BB���/�.

��������0A�A���6� &2�,�*���� ��&���A &$�BB�66�/,,B���/�.

���������F

��������5

����������������3��0����0��,�8��

���������AA����,�������B��B*�� �0�/,���3��0���AV???B.

��������������� �0�/,�������/8����1�09�������0��,�8�

������������ �0�/,���1*�� �0�/,���1A��

������������� �0�/,���1A��BB.

�������������F���*�/*(��,AG������/8�;/� &��HIGB.

��������������0�8�;��(/��09��:������/8

Page 334: Java in Datenbanksystemen

��. ����������� �������������������

����������,�8��4����6��F���*�/���=���$�,,��AB.

�������������$����!���!���6�/,,.

�����������������/6?.

����������0���A��)6?.�)J���3��2"=.�)KKB

����������5

��������������F���*�/*(��,AG /���,�/0�"���G�K�)B.

�������������@�+,�!���6�5������=�-�#��$�����������N.

���������������,��A!��*�1ABB

��������������������������/KK.

������������!��*�,���AB.

����������N

�������������F���*�/*(��,AG &�:/8��00���/����,�/

��������������/���=���$�,,��AB�G�K�A�F���*�/���=���$�,,��AB

����������������4���B�K�G���,,����/��GB.

�������������������,/��������-----------------

��������������*�,���AB.

��������N

�����������/�09��,������ &��#��,�������,/8�����������������������

�����������,,������$���������0����,*���������1��(��

������������A����1��(����B

��������5

������������ &2�,�*��������1��(��A�B.

��������N

������������A�1��(����B5

�������������F���*�/*(��,AGI����#��,�����8��������IGB.

�������������*(������=����AB.

��������N

����N���������$��

N

Im Unterschied zu Beispiel 9.9 wird in Beispiel 9.10 eine Instanz ���� der KlasseOracleConnection definiert. Dies ist notwendig, damit die SetDefaultRowPrefetch()-Methode verwendet werden kann. Aus dem Kontext wird mittels der getConnec-tion()-Methode die Instanz der Klasse Connection ermittelt und in eine Instanz derOracleConnection-Klasse umgewandelt.

Tabelle 9.5 zeigt die Messergebnisse mit unterschiedlichen Werten für setDefault-RowPrefetch.

�-�� �������"�7��-5�"�� (()*��34��,����

�������"�6�#������-;'(((= (() �*.'�,�����

�������"�6�#������-�;3(((= (() (�4+.�,�����

�������"�6�#������-�;*(((= (()�+�4'4�,�����

�������"�6�#������-�;�(((= (()�3�.4'�,�����

�������"�6�#������-�;�((= (()�4� �+�,�����

#���$$���%2&�����'���$���(������ �����(���$��(� �7���� �5�������������$�/*������(89�:��(��

Page 335: Java in Datenbanksystemen

;������ ���� � ��2

Wie aus Tabelle 9.5 ersichtlich, kann die Festlegung des setDefaultRowPrefetch-Wer-tes signifikante Performance-Vorteile bringen. Andererseits wird ab einer gewisserGröße des Wertes das Performance-Verhalten wieder etwas schlechter. (Dies kanndamit erklärt werden, dass es eine optimale Anzahl von Reihen gibt, die in einemDurchgang vom Client empfangen werden sollen. Die Aufgabe des Benutzers ist, die-sen Wert durch Tests zu ermitteln.)

��4 >� ������ ��

Die von uns untersuchten Fälle können in zwei Gruppen unterteilt werden:

� unterschiedliche Programmierarten

� Verwendung verschiedener Sprachmittel bei SQLJ.

Die Verwendung verschiedener Sprachmittel ist in den meisten Fällen herstellerspezi-fisch. Aus diesem Grund haben wir uns auf die SQLJ-Sprachmittel des Oracle-Systemskonzentriert.

Dieses Kapitel ist das abschließende Kapitel des SQLJ-Teiles des Buches. Im nächstenKapitel werden Java-Prozeduren beschrieben.

Page 336: Java in Datenbanksystemen
Page 337: Java in Datenbanksystemen

��������������� ��������������������

Page 338: Java in Datenbanksystemen
Page 339: Java in Datenbanksystemen

�� ��������������������������� ������� ����������� �

Die Implementierung von gespeicherten Prozeduren und Triggern mit Hilfe von SQLJbzw. JDBC stellt einen weiteren sehr wichtigen Bereich dar, wo Java verwendet wird.Der Grund für die Verwendung dieser Sprache liegt in der Vereinheitlichung derImplementierung.

Gegenwärtig werden diese Datenbankobjekte bei den herkömmlichen Systemen pro-prietär implementiert. Das heißt, dass jedes Datenbanksystem eine herstellerspezifi-sche prozedurale Sprache verwendet, um gespeicherte Prozeduren und Trigger zuimplementieren: Oracle benutzt PL/SQL (Procedure Language/SQL), Informix SPL(Stored Procedure Language), während IBM keine spezielle prozedurale Sprache hat.

Für Java gilt grundsätzlich, dass mit dieser Sprache alle Datenbankhersteller eine ein-heitliche Schnittstelle verwenden können, damit Prozeduren und Trigger portierbarwerden. (Die Standardisierung von SQLJ durch das ANSI-Gremium zielt u.a. auch indiese Richtung.) Wie aus der Erörterung in diesem Kapitel ersichtlich wird, ist diesesZiel nur zum Teil verwirklicht worden.

Die Einführung von Java für die Erstellung der gespeicherten Prozeduren und Triggerhat auch einen (möglichen) Nachteil: Weil es sich bei Java um eine objektorientierteSprache handelt, werden mit dieser Sprache Klassen und Klasseninstanzen in eineDatenbankumgebung, die überwiegend prozedural ist, eingeführt. Diese Befürchtungist aus unserer Sicht ungerecht: Erstens erweitern alle Datenbankhersteller mit Nach-druck ihre relationalen Systeme mit objektorientierten Konzepten (siehe Kapitel 2),und zweitens ändert es nichts an den Grundlagen von Strukturen, die in einer Daten-bank existieren, ob man eine prozedurale oder objektorientierte Sprache für die Daten-bearbeitung nimmt.

Obwohl die Verwendung der Java-Sprache bei der Erstellung von serverseitigen Daten-bankobjekten einer Vereinheitlichung dienen soll, existieren noch zu große Unterschiedebei den verschiedenen Datenbanksystemen, besonders in den Entwicklungsschritten,die notwendig sind, um ein serverseitiges Datenbankobjekt zu registrieren. Aus diesemGrund werden wir die Erstellung dieser Objekte in zwei getrennten Abschnitten (fürOracle und IBM DB2) beschreiben.

Page 340: Java in Datenbanksystemen

��� ������������ ��������� ���������������� �������������������

���� �� �!�������������"��!#� ������������������� $�!��

Generell existieren insgesamt zwei Möglichkeiten, wie serverseitige Datenbankobjekteerstellt werden können:

� auf der Client-Seite

� auf der Server-Seite.

Bei der ersten Alternative wird das Java-Programm (d.h. ein JDBC- oder SQLJ-Pro-gramm) auf der Client-Seite übersetzt und danach werden die generierten Klassen- (undRessource-)Dateien auf dem Server gespeichert. Bei der Erstellung des Java-Programmsauf der Server-Seite wird das entsprechende JDBC- bzw. SQLJ-Quellprogramm mit demdort existierenden Übersetzer übersetzt.

Die Alternative mit der Implementierung auf der Client-Seite ist aus unserer Sicht bes-ser, weil der Übersetzer auf dem Client bessere Möglichkeiten für die Fehlerbearbei-tung bietet. Zusätzlich dazu unterliegt die Implementierung auf dem Server gewissenBesonderheiten, die auch im Programm berücksichtigt werden müssen. Zu diesengehören:

� eine explizite Verbindung zur Datenbank ist nicht notwendig (weil das Programmschon innerhalb einer Datenbank auf der Server-Seite abläuft)

� die (einzige) existierende Verbindung kann nicht geschlossen werden

� gewisse Laufzeitpakete (wie z.B. oracle.sqlj.runtime.Oracle) müssen nicht impor-tiert werden, weil sie auf dem Datenbank-Server direkt zur Verfügung stehen.

Die Implementierung eines JDBC- bzw. SQLJ-Programms, das eine gespeicherte Proze-dur erstellt, wird bei Oracle in sieben Schritten durchgeführt:

1. Das SQLJ-Programm (bzw. JDBC-Programm) erstellen und übersetzen

2. Klassen in ein Java-Archiv zusammenfassen (optional)

3. Vorher registrierte Daten entfernen (optional)

4. Die übersetzten Dateien im Datenbank-Server registrieren

5. Testen, ob die Registrierung erfolgreich war

6. Erstellen eines Wrappers mit Hilfe der CREATE FUNCTION- bzw. CREATE PRO-CEDURE-Anweisung

7. Aufrufen der gespeicherten Prozedur.

Die folgenden Abschnitte erläutern die oben genannten Schritte.

Page 341: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� ���

������ ����%����"������&���� '��

Generell kann ein serverseitiges Datenbankobjekt sowohl mit Hilfe von JDBC als auchmit SQLJ erstellt werden. Aus diesem Grund wird dieser Abschnitt zwei logisch iden-tische Programme haben. Beispiel 10.1 zeigt ein JDBC-Programm, während Beispiel10.2 das entsprechende SQLJ-Programm darstellt.

Beispiel 10.1

���������� �������������������������������������������������������� !�"���������������#���������������#�$�%�&�������� !�"�����!���������'()*+�,��-����!����������+���� �����.� /0�-�����������1(������2�3��������������� ������4��������������1���5����!������������������.� ����/�+���� 67��� 0�-������ 687#1(������2�3��������������� ������4��������������1���5����!�������������!��� ��9���/���!������0�-�������������������:�;<<=>8���5����!���������������������������/�+���� �������+���� �����������������������+���� 67������0�-�������������#8���������%������-������������������?��!����� ��!���������+�������!�����������*��������������#���������(����.� ��� ��*���������/1��!�@������@����������10���������+���� �� ��#�1AB+9�2�AB2,���,'9C2�?�DE9+�/�F1�G������G�1F����������F1�G�������G�1F��1�G��������G�101���������+�������������#����������+�������/0�������������������������4���������������#�������3�����E����/� �0�������������������/0�������5����4�/+HD93���������0�-������������������4����!�� �������*������������ �!���������������687#�� ��.��� �/0����������������I:�������5�����������687#1C������4������ �������J1��������������������55

ORACLE

Page 342: Java in Datenbanksystemen

��! ������������ ��������� ���������������� �������������������

Bei der Klasse JDBCSrvOra handelt sich um eine Java-Klasse, die auf dem Oracle-Ser-ver gespeichert wird und deren Methoden dann vom Client (oder Server) aus aufgeru-fen werden können. Da die Länge des Prozedurnamens auf etwa 30 Zeichenbeschränkt ist, empfiehlt es sich, den Klassennamen so kurz wie möglich zu halten.

Bei Oracle werden gespeicherte Prozeduren in Java folgendermaßen deklariert:

���!��������������$.��4�������&/$�������&0

Im Gegensatz zu gespeicherten Funktionen ist ihr Rückgabewert immer void.

Gespeicherte Funktionen werden mit:

���!����������$���� !��%�&�$.��4�������&/$�������&0

deklariert, können also Rückgabewerte besitzen und sind wie alle gespeicherten Pro-gramme in Oracle static.

Die Klasse JDBCSrvOra in Beispiel 10.1 implementiert insgesamt drei Funktionen:

� getEuro()

� testMsg()

� insertProjekt

und eine gespeicherte Prozedur:

� testMsgProc.

Die gespeicherte Funktion testMsg() gibt lediglich eine Zeichenkette (vom Typ String)zurück. Im Vergleich dazu kann eine gespeicherte Prozedur wie testMsgProc norma-lerweise keinen Wert zurückgeben, sondern nur Parameter übernehmen und dannAufgaben ausführen. (Im Beispiel wird dennoch mit Hilfe eines Vektors mit Zeichen-kettenelementen ein Wert aus dieser Prozedur zurückgegeben.)

Für eine praktische Demonstration einer gespeicherten Funktion wurde getEuro()implementiert, welche den übergebenen Mark-Wert in Euro umrechnet und zurück-gibt. Die etwas komplexere Funktion insertProjekt() übernimmt mehrere Parameterund fügt damit eine neue Zeile in die Tabelle projekt ein. Der Rückgabewert teilt demAufrufer mit, ob ein Fehler aufgetreten ist. (Der zusätzlich implementierte vierte Para-meter, der als Vektor mit Zeichenkettenelementen definiert ist, dient zur Rückgabe

�������

Oracle unterscheidet zwischen gespeicherten Prozeduren und gespeicherten Funk-tionen. Die ersten sind die Server-Routinen, die keinen Rückgabewert haben, wäh-rend gespeicherte Funktionen immer einen Rückgabewert liefern. (Wir werden denNamen »gespeicherte Programme« als übergeordneten Begriff verwenden, umbeide Begriffe gleichzeitig anzusprechen.)

Page 343: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� ���

einer textuellen Statusmeldung. Bei Oracle kann auf diese Weise eine Art Debugging-Mechanismus implementiert werden.) Da zum Einfügen einer neuen Reihe eineInstanz der Klasse Statement notwendig ist, welche aber zur Erzeugung eine Instanzder Klasse Connection benötigt, muss man bei einer gespeicherten Prozedur ein Con-nection-Objekt mit Hilfe von

(����.� ��� ��*���������/1��!�@������@����������10�

erzeugen.

Die Übersetzung des JDBC-Programms in Beispiel 10.1 wird mit Hilfe des java-Kom-mandos durchgeführt. (Für weitere Einzelheiten siehe den Abschnitt »Übersetzungund Ausführung eines JDBC-Programms« in Kapitel 4.)

Bei Verwendung von SQLJ (anstatt JDBC) ist der in Beispiel 10.1 dargestellte Verbin-dungsaufbau nicht nötig, wie das folgende Beispiel zeigt.

Beispiel 10.2

���������� ������!���������+HD'+�,��-

�����!����������+���� �����.� /0�-�����������1(������2�3��������������� ������4��������������1���5����!������������������.� ����/�+���� 67��� 0�-������ 687#1(������2�3��������������� ������4��������������1���5����!�������������!��� ��9���/���!������0�-�������������������:�;<<=>8���5����!���������������������������/�+���� �������+���� �����������������������+���� 67������0�-��������%�-��������K� �-AB+9�2�AB2,���,'9C2�?�DE9+/@������@������@�������0�5�������5����4�/+HD93���������0�-������������������4����!�� �������*������������ �!���������������687#�� ��.��� �/0����������������I:�������5���������687#1C������4������ �������J1������������:���55

Die Übersetzung des SQLJ-Programms in Beispiel 10.2 wird mit Hilfe des folgendenSQLJ-Kommandos durchgeführt:

� ���I���L�����+HD'M*�����M������� ��

ORACLE

Page 344: Java in Datenbanksystemen

��� ������������ ��������� ���������������� �������������������

Im obigen Kommando verwenden wir die Option ser2class, um damit alle bei derÜbersetzung generierten Profile als .class-Dateien zu speichern. (Standardmäßig wer-den solche Dateien mit dem Suffix .ser gespeichert.) Diese Maßnahme wird durchge-führt, damit die Voraussetzungen für die Verwendung des loadjava-Dienstprogrammsvereinfacht werden (siehe unten).

�����( ����)��������������*!#���'�������+�����

Bevor .class- und .ser-Dateien mit Hilfe des Oracle-Dienstprogramms loadjava inBibliothekseinheiten (database library units) gespeichert werden, ist es möglich, alleübersetzten Klassen in ein Java-Archiv zu speichern. (Falls das nicht geschieht, müssenalle .class- und .ser-Dateien mit dem loadjava-Kommando explizit angegeben werden,was die Kommandoangabe wesentlich komplexer macht.) Die Speicherung in ein Java-Archiv namens JDBCSrvOra geschieht mit dem in Kapitel 3 beschriebenen jar-Kom-mando und sieht in diesem Fall folgendermaßen aus:

���I��8�'()*+�,�����'()*+�,�������

Die c-Option erstellt ein neues Archiv, während die v-Option einen ausführlichenBericht über die Ausführung des jar-Kommandos in die Standard-Fehlerdatei (stderr)erstellt. Die Option f spezifiziert, dass das Archiv in die Datei gespeichert werden soll,deren Name als nächster Parameter im jar-Kommando erscheint. Schließlich unter-drückt die 0-Option die Komprimierung von .java- und .ser-Dateien. Diese Option istunbedingt notwendig, weil loadjava komprimierte Dateien nicht verarbeiten kann.

�����, ��#������ �� ��$���� ���� +����

Klassen, Ressourcen und Schemaobjekte, die anschließend mit dem Dienstprogrammloadjava auf dem Datenbank-Server gespeichert werden, können schon existieren. Umentsprechende Fehlermeldungen in einem solchen Fall auszuschließen, kann dasDienstprogramm dropjava verwendet werden. Dieses Dienstprogramm löscht alleaufgelisteten Objekte vom Datenbank-Server. Mit dem folgenden Kommando:

������I������������� ���'()*+�,������

wird die Datei JDBCSrcOra.class z.B. auf dem Datenbank-Server gelöscht.

Falls alle .sqlj- .class- und .ser-Dateien, die in einem Archiv namens JDBCSrvOra.jargespeichert sind, gelöscht werden sollen, sieht das entsprechende dropjava-Kom-mando so aus:

������I������������� ���'()*+�,����

Page 345: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� ��"

�����- )������������ ��������������� ����

Das Oracle-Dienstprogramm namens loadjava wird benutzt, um die .class-Dateien inBibliothekseinheiten, die Klassen-Schemaobjekte (class schema objects) genannt werden,zu laden. Genauso werden von diesem Dienstprogramm die .ser-Dateien (falls exis-tent) in ähnlichen Einheiten namens Ressource-Schemaobjekte (resource schema objects)geladen. Alle erstellten Bibliothekseinheiten werden anschließend auf dem Daten-bank-Server gespeichert.

Die Syntax des loadjava-Kommandos unterscheidet sich, abhängig davon, welcherTreiber verwendet wird. Falls der JDBC OCI8-Treiber benutzt wird, sieht das Laden derJDBCSrvOra.class-Datei so aus:

�����I��!����I�������I������������� ���'()*+�,������

(Der JDBC OCI8-Treiber ist der Standard-Treiber für das loadjava-Dienstprogramm.)Die Option verbose druckt schrittweise einen Bericht über die Ausführung des load-java-Kommandos. Die andere Option – resolve – steuert die unmittelbare Auflösungder Klassenreferenzen. (Falls diese Option ausgelassen wird, wird die Auflösung derKlassen erst bei der Programmausführung in die Wege geleitet.)

Falls der sogenannte thin-Treiber verwendet werden soll, müssen sowohl die URL alsauch die thin-Option angegeben werden:

�����I��!����I�������I�4���I������������� ��N����4���@:<L:@�����8:�'()*+�,������

�����. ��� ��/��������0���� �������+�����!#� �

Oracle enthält eine Systemtabelle namens user_objects, die wie ihr Name schon sagt,die Information über alle vom Benutzer erstellten Datenbankobjekte beinhaltet.(user_objects, genauso wie alle anderen Systemtabellen bei Oracle ist im Grunde keineTabelle, sondern eine Sicht.) Diese Sicht kann verwendet werden, um zu prüfen, ob diemit loadjava erstellten Objekte tatsächlich auf dem Server gespeichert sind.

Um die Sicht user_objects zu verwenden, muss man die Namen der Objekte kennen.Wie wir schon erläutert haben, werden nach der Ausführung des loadjava-Komman-dos sowohl Klassen- als auch Ressource-Schemaobjekte erstellt. Der volle Name einesKlassen-Schemaobjektes wird aus dem Paketnamen und Klassennamen zusammenge-

�������

Alle .class- und .ser-Dateien können vor der Ausführung des loadjava-Komman-dos in ein Archiv gespeichert werden. Dies vereinfacht die Syntax des Kommandos.Genauso können alle .ser-Dateien in .class-Dateien umgewandelt werden, was eineweitere Vereinfachung mit sich bringt.

Page 346: Java in Datenbanksystemen

��# ������������ ��������� ���������������� �������������������

setzt, wobei jeder Punkt durch ein Zeichen »/« ersetzt wird. (Die Notation der Res-source-Schemaobjekte wird hier nicht erläutert, weil wir davon ausgehen, dass alle.ser-Dateien nicht existent sind, weil sie mit Hilfe der Option -ser2class des sqlj-Dienstprogramms in .class-Dateien umgewandelt werden können.)

Mit der folgenden SELECT-Anweisung kann getestet werden, ob das Objekt JDBC-SrvOra, das sich im Paket P befindet, auf dem Server gespeichert ist:

+9D9*2�����,.�����M�!������OP9�9��!����M����#�F��'()*+�,�F�

Falls der vollqualifizierte Name eines Klassen-Schemaobjektes länger als 31 Zeichen istoder unerlaubte Zeichen enthält, wird von Oracle ein gekürzter Name (short name)generiert. In diesem Fall kann die Funktion dbms_java.shortname verwendet werden,die als Parameter den vollqualifizierten Namen nimmt und den gekürzten Namenzurückliefert:

+9D9*2�����,.�����M�!������OP9�9����!����M����#��!��M���4�������/F��'()*+�,�F0�

Diese zweite SELECT-Anweisung ist genereller, weil sie unabhängig davon, ob dergekürzte Name vom System erstellt wurde oder nicht, die Antwort über das Laden desObjektes P.JDBCSrvOra liefert.

�����1 �� ������������2�""����� ����30�*���4563��$6�*� ������

Der letzte Schritt in der Entwicklung eines Java-Programms, das serverseitige Daten-bankobjekte implementiert, ist die Erstellung des SQL-Wrappers für dieses Objekt. Inder Informatik kennzeichnet Wrapper eine Softwarekomponente, die verwendet wird,um ein Programm oder System zu umhüllen und damit zu transformieren, damit eseiner anderen Softwarekomponente angepasst wird. Ein SQL-Wrapper kennzeichnetdementsprechend ein SQL-Skript, das ein Java-Programm für den Datenbank-Serverso umwandelt, dass dieses dem Server als eine in PL/SQL-Sprache geschriebenegespeicherte Prozedur erscheint.

Ein Wrapper für ein Java-Programm wird entweder mit der SQL-Anweisung CREATEPROCEDURE oder mit CREATE FUNCTION erstellt. CREATE PROCEDURE wirdverwendet, falls eine gespeicherte Prozedur erstellt werden soll, während CREATEFUNCTION eine gespeicherte Funktion erzeugt.

Die Syntax der CREATE PROCEDURE-Anweisung sieht folgendermaßen aus:

*�9�29���,*9(E�9�����M����6/���:�6�����L����7�0�7���6�E2PA(�-(9�AB9��Q�*E��9B2ME+9�5�7�6����DD9DM9B�)D97��6(929�.ABA+2A*7��-A+�Q��+�5�D�BRE�R9�'�?����B�.9�ST���4����M���/�M�%�M���:�6���M�%�M���L����7T

Page 347: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� ��$

Die Angabe param1, param2, ... in der Syntax steht für:

�������M����6AB�Q�,E2QAB,E27�� �M�%�

Wir werden Angaben der CREATE PROCEDURE-Anweisung nicht einzeln erläutern,sondern Teile des Programms in Beispiel 10.2 verwenden, um wichtige Angaben zubeschreiben. (Die Erläuterung aller Angaben kann im Oracle-Manual Java Stored Pro-cedures Developer’s Guide gefunden werden.)

Als Beispiel einer CREATE PROCEDURE-Anweisung verwenden wir folgende in Bei-spiel 10.3 existierende Anweisung:

*�9�29�,���9�D�*9���,*9(E�9�����.� ����/�� �,E2�?��*P��L0��+�D�BRE�R9�'�?��B�.9�F'()*+�,������.� ����/���� �+���� 670F�

Mit dieser Anweisung wird die gespeicherte Prozedur namens testMsgProc erstelltbzw. ersetzt, falls existent. Der einzige Parameter dieser Prozedur ist msg, wobei essich um einen OUT-Parameter vom Typ VARCHAR2 handelt. Die Angabe AS LAN-GUAGE JAVA bedeutet, dass die Prozedur mit Hilfe der Java-Sprache implementiertist.

Die Angabe NAME enthält einen in Apostrophen geschriebenen vollqualifiziertenDateinamen der Java-Klasse, d.h. den Namen der Java-Klasse und der entsprechendenMethode. In dem obigen Beispiel handelt es sich um die Klasse JDBCSrvOra (Beispiel10.1) und ihre Methode testMsgProc(). Zusätzlich enthält die NAME-Angabe denParameter der Methode (in unserem Fall String[]).

Die Syntax der CREATE FUNCTION-Anweisung gleicht der Syntax der CREATEPROCEDURE-Anweisung:

*�9�29��EB*2A,B�����M���6/���:�6�����L����7�0�7��92E�B�� �M�%����6�E2PA(�-(9�AB9��Q�*E��9B2ME+9�5�7�6����DD9DM9B�)D97��6(929�.ABA+2A*7��-A+�Q��+�5�D�BRE�R9�'�?��B�.9�S���4����M����T/�M�%�M���:�6���M�%�M���L����7�6��������M�%�M���7T

wobei param1, param2,.. dieselbe Syntax haben wie bei der CREATE PROCEDURE-Anweisung.

�������

Während SQL-Anweisungen case insensitive sind (d.h. sie können mit Groß- oderKleinschreibung geschrieben werden), sind Java-spezifische Angaben case sensitive.Aus diesem Grund muss z.B. der Name einer Java-Klasse genau so geschriebenwerden, wie er im Quelltext angegeben ist.

Page 348: Java in Datenbanksystemen

��% ������������ ��������� ���������������� �������������������

Den ersten Unterschied zu der CREATE PROCEDURE-Anweisung stellt die RETURN-Angabe dar. Diese Angabe, wie bei gespeicherten Funktionen üblich, liefert den Rück-gabewert der Funktion. Zweitens existiert in der NAME-Angabe eine weitere return-Anweisung, die den Datentyp des Rückgabewertes der Java-Methode spezifiziert.Damit steht die erste RETURN-Anweisung mit der SQL- und die zweite mit der Java-Sprache in Zusammenhang.

Wir werden wieder eine Anweisung aus Beispiel 10.3 verwenden, um die Syntax derCREATE FUNCTION-Anweisung zu erläutern:

*�9�29�,���9�D�*9��EB*2A,B� ��9���/�����BE.)9��0��92E�B�BE.)9����+�D�BRE�R9�'�?��B�.9�F'()*+�,�� ��9���/����!���0�����������!��F�

Dementsprechend wurde in dem obigen Beispiel die gespeicherte Funktion getEuroerstellt, die einen Parameter (value) hat und einen Rückgabewert vom Typ NUMBERliefert. Des Weiteren liefert die Methode getEuro einen Wert mit dem Java-Datentypdouble zurück.

�����7 *�+�+������������"��!#� ����������

Bei Oracle existieren sehr viele unterschiedliche Möglichkeiten, wie ein gespeichertesProgramm aufgerufen werden kann. Der Aufruf kann:

� innerhalb eines PL/SQL-Blocks

� innerhalb einer Datenmodifikationsanweisung (SELECT, INSERT, UPDATE undDELETE) (Dies gilt nur für gespeicherte Funktionen.)

� mit Hilfe der CALL-Anweisung innerhalb von SQL*Plus bzw. Pro*C

� innerhalb eines Java-Programms (JDBC bzw. SQLJ)

erscheinen.

Weil dieses Buch die Java-Sprache behandelt, werden wir uns nur mit dem letzten Punktder obigen Liste befassen. Wir werden mit zwei Beispielen zeigen, wie der Aufruf derProzeduren, die auf dem Datenbank-Server gespeichert sind, möglich ist. Beispiel 10.3stellt ein JDBC-Programm dar, mit dem Prozeduren testMsg, getEuro, insertProjektund testMsgProc, die mit Beispiel 10.1 bzw. 10.2 erstellt wurden, registriert und ausge-führt werden können. Damit umfasst dieses Programm in Wirklichkeit nicht nur denletzten, sondern auch den vorletzten Schritt, die Erstellung eines Wrappers.

�������

Bei der CREATE PROCEDURE- bzw. CREATE FUNCTION-Anweisung werdenlogische Fehler erst beim Prozedur- (Funktion-) Aufruf gemeldet. Damit werdenz.B. die Inkonsistenzen zwischen den Prozedurparametern und den entsprechen-den Parametern der Java-Methoden erst beim Ablauf gemeldet.

Page 349: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� ��&

Beispiel 10.3

�������E������������������������������� ������!���������'()*M*�����M,����-������������������().+�#�()E�����,��*D9�������!��U�� ���?��!��������()IV� �����������������*��������������#����������������+�������������#����������������������+������#�������������������������������������������������������!�����������������/+���� �� 670����-����������/�J()E���������(�!��(����/().+00������������������/�/����#�()E������������(�)��/().+00�##�����0������������������%��������-������������+%����������������/1?��!����� ����()�,CW�10������������������#����������+�������/0�������������+%��������������/19���������������������10�������������������3�����/1*�9�29�,���9�D�*9��EB*2A,B�����.� ��92E�B�������������?��*P��L��+�D�BRE�R9�'�?��B�.9�F'()*+�,������.� /0������������������������ �+���� F�10�������������������3�����/1*�9�29�,���9�D�*9��EB*2A,B� ��9���/�����������������BE.)9��0��92E�B�BE.)9���+�D�BRE�R9�'�?��B�.9�������������F'()*+�,�� ��9���/����!���0�����������!��F�10�������������������3�����/1*�9�29�,���9�D�*9��EB*2A,B��������������������������/�������4�L�����������4�L����������������������������������������4�L0��92E�B�BE.)9���+�������������D�BRE�R9�'�?��B�.9�F'()*+�,���������������/����������������� �+���� ������ �+���� ������������������������ �+���� 67�0�����������F�10�������������������3�����/1*�9�29�,���9�D�*9���,*9(E�9�����������������.� ����/�� �,E2�?��*P��L0��+�D�BRE�R9�'�?��B�.9�������������F'()*+�,������.� ����/���� �+���� 670F�10�������������+%����������������/1����� �W�10�����������������������������E(�@������������+%����������������/1�����F+9D9*2���������R929E�,/������0���������������,.��������F������10�������������������+������#�������3�����H���%/1+9D9*2���������������������R929E�,/������0���,.��������10�������������+%����������������/1(.W�W�9E�,10�������������"4���/�����3�/00-����������������+%����������������/��� ������/:0G�1��W�1�G�������������������� ������/L00�������������5��������������IIIIIIIIIIIIIIIIII

ORACLE

Page 350: Java in Datenbanksystemen

�"� ������������ ��������� ���������������� �������������������

������������+%����������������/1W�������������������.� ������10�������������*��!��+��������������#�����������*��/1-X�#���������������������.� �510���������������������*���������� ���4�������� ��������������()E������4�"O���� �/������ ��O���� �/00��������������������� �����,���������/:��2%����?��*P��0�����������������������������4����������������������3�����/0�������������+���� ���3��#������� ��+���� /:0�������������+%����������������/19� �!���@�1G��3�0�������������+%����������������/1W�������������������.� ����������������������10�������������������#�����������*��/1��������.� ����/X010���������������������*���������� ���4�������� ��������������()E������4�"O���� �/������ ��O���� �/00��������������������� �����,���������/:��2%����?��*P��0�����������������������������4����������������������3�����/0���������������3��#������� ��+���� /:0�������������+%����������������/19� �!���@�1G��3�0����������������?��!���������������*�������������@������������+���� ���M���#�1�>1�������������+���� ���M����#�1?����1�������������������������#�>=<<<<�������������������#�����������*��/1-X�#������������������/�X���X���������������X��X0�510���������������������*���������� ���4�������� ��������������()E������4�"O���� �/������ ��O���� �/00�������������������� !�"����������������������������������� �����,���������/:��2%����AB29R9�0��������������������� �����,���������/<��2%����?��*P��0��������������������������"��������������������������+���� /L���M��0����������������������+���� />���M���0��������������������������/Y�������0�����������������������������4���������������+%����������������/1W�������������������������10��������������������3�����/0�������������������� !�"���������������������������������#������� ��A��/:0�������������+���� �����#������� ��+���� /<0������������+%����������������/19� �!���@�1G������G1W���4���@�1G���0��������������������������"��������������������������+���� /L�1�������:L10����������������������+���� />�1�����10��������������������������/Y�<888880�����������������������������4����������U ���4�����4���!�4����� ������������+%����������������/1W�������������������������10��������������������3�����/0��������������������#������� ��A��/:0���������������/������$80����!�����4�������4��������� ������

Page 351: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� �"�

����������������+%����������������/1��4���@�1G������ ��+���� /<00��������������������������������������� !�"������ �!������������������+%����������������/19� �!���@�1G������0����������������!��4�����!�������������������������������������������������������/0����������������������/0���������5���������������4����4��'()*I��4���!�4����� @IIIIIIIIIIIII��������������+HDI.��4�����"����������������+HD93������������������4/+HD93���������0��������-������������()E������4�"+HD93�������/�0���������5�����������4/93���������0-������������+%����������������/1W�III�E�!����������4����IIIW�10��������������������+���2���/0���������5����5��9�������.��5

Die Ausgabe des Beispiels 10.3 sieht folgendermaßen aus:

?��!����� ����()�,C9�������������������������� ������F+9D9*2���������R929E�,/������0���,.��������F������(.��������9E�,:=Z<88�8��;<><<�;Y:L8888�8��Z:><<�8L[;<888�8���Y=<[L�[>������������������.� ������9� �!���@�(������2�3��������������� ������4��������������������������������������9� �!���@�:��4���@�C������4������ �������J��������������������������4���@�,��I8:Y8:@�9�� ��� ����O������� ��\�����+����

Im ersten Teil des Beispiels 10.3 werden mit Hilfe der CREATE PROCEDURE- bzw.CREATE FUNCTION-Anweisung mehrere Wrappers für gespeicherte Programmeerzeugt. Obwohl die Ausführung dieser Anweisungen normalerweise nur einmalgestartet wird (und nicht unbedingt in einer Client-Anwendung wie Beispiel 10.3)haben wir es wegen der Übersichtlichkeit so wie im Beispiel implementiert.

Der erste Funktionsaufruf erfolgt innerhalb einer SELECT-Anweisung mit

+9D9*2���������R929E�,/������0���,.��������

Die jeweiligen Werte kann man dann aus der Ergebnismenge mit Hilfe von rs.get-Float() auslesen. Hier muss, genau wie bei der Implementierung und der Erstellungdes Wrappers auf korrekte Typ-Konvertierungen zwischen der Datenbank und Javageachtet werden.

Page 352: Java in Datenbanksystemen

�"! ������������ ��������� ���������������� �������������������

Der Aufruf der übrigen Funktionen und Prozeduren erfolgt über eine Instanz derKlasse PreparedStatement, wobei hier die Syntax bezüglich der Rückgabewerte zubeachten ist. Der gesamte Aufruf muss in geschweiften Klammern stehen, wenn derAufruf einen Wert zurückliefert:

*��!��+��������������#�����������*��/1-X�#���������.� �510�

Mit Hilfe von

�� �����,���������/:��2%����?��*P��0�

muss der entsprechende Rückgabetyp im PreparedStatement festgelegt werden, bevorer gelesen werden kann. Im Falle der Prozedur steht der Rückgabewert lediglich in derParameterleiste und kann, obwohl als String[] deklariert, über getString() gelesenwerden.

Die anderen beiden Funktionsaufrufe, welche die Methode insertProjekt() aufrufen,verwenden zusätzlich mehrere Parameter, um eine neue Reihe in die Tabelle projektvorzunehmen. Im ersten der beiden Aufrufe wird eine Erfolgsmeldung über den letz-ten Parameter ausgelesen. Beim letzten Funktionsaufruf wird absichtlich eine Instanzder Klasse SQLException am Server erzeugt. Der Rückgabewert der Funktion zeigteinen Fehler an, der über den letzten Parameter gelesen werden kann.

Das folgende Beispiel ist ein SQLJ-Analogon zu Beispiel 10.3.

Beispiel 10.4

�������E������������������������������� ������������ ���������������(�����*����3����!���������+HD'M*�����M,����-�������������������().+�#�()E�����,��*D9�������!��U�� ���?��!��������()IV� �����������������*��������������#��������������������������������������������������������B����A����������K� ����!������������������A����/����������0�������!�����������������/+���� �� 670����-����������/�J()E���������(�!��(����/().+00������������������/�/����#�()E������������(�)��/().+00�##�����0������������������%��������-������������(�����*����3�����(�����*����3�/��"�������������(�����*����3�/���00�������������+%����������������/1?��!����� ����()�,CW�10�

ORACLE

Page 353: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� �"�

������������+%��������������/19���������������������10�������������K� ��-*�9�29�,���9�D�*9��EB*2A,B�+HD'����.� ��92E�B�������������?��*P��L��+�D�BRE�R9�'�?��B�.9�F+HD'+�,������.� /0������������������������ �+���� F��5�������������K� ��-*�9�29�,���9�D�*9��EB*2A,B�+HD' ��9����/�����������������BE.)9��0��92E�B�BE.)9���+�D�BRE�R9�'�?��B�.9�������������F+HD'+�,�� ��9���/����!���0�����������!��F��5�������������K� ��-�*�9�29�,���9�D�*9��EB*2A,B�+HD'�������������/�������������������4�L�����������4�L����������������������������������������4�L0��92E�B�BE.)9���+���������������������D�BRE�R9�'�?��B�.9�F+HD'+�,���������������/����������������� �+���� ������ �+���� ������������������������ �+���� 67�0�����������F��5�������������K� ��-�*�9�29�,���9�D�*9���,*9(E�9�+HD'����.� ����/�� �������������,E2�?��*P��L0��+�D�BRE�R9�'�?��B�.9�������������F+HD'+�,������.� ����/���� �+���� 670F��5�������������+%����������������/1����� �W�10�����������������������������E(�@������������+%����������������/1�����F+9D9*2���������������������+HD'R929E�,/������0���,.��������F������10�������������A���������������������K� �������#�-�+9D9*2���������+HD'R929E�,/������0���,.���������������������5�������������+%����������������/1(.W�W�9E�,10�������������������������#����������#�����������������"4����/����0�-�������������������K� ��-��92*P�@�����AB2,�@���������@�����5�����������������������/������������4/00�!�����������������������+%����������������/�������G�1��W�1G�����0�������������5����������������������/0���������������IIIIIIIIIIIIIIIIII������������+%����������������/1W���������������+HD'����.� ������������������10�������������+���� ���3��#�11�������������K� ����3�#�-?�DE9+/�+HD'����.� /00�5�������������+%����������������/19� �!���@�1G��3�0�������������+%����������������/1W���������������+HD'����.� ����������������������10�������������K� ��-�*�DD�+HD'����.� ����/@,E2���3�0�5�������������+%����������������/19� �!���@�1G��3�0����������������?��!��������P����3��������������������@������������+���� ���M���#�1�>1�������������+���� ���M����#�1?����1�������������������������#�>=<<<<������������������������#�8�������������+���� �����#�11�������������+%����������������/1W������+HD'�������������������10�������������K� ���������#�-�?�DE9+/�+HD'�������������/@��M����������������@��M�����@��������@,E2����0�0�5�������������+%����������������/19� �!���@�1G������G1W���4���@

Page 354: Java in Datenbanksystemen

�"� ������������ ��������� ���������������� �������������������

�������������1G���0��������������������������"�������������������M���#�1�������:L1���������������M����#�1�����1��������������������#�<88888�����������������������������4����������U ���4�����4���!�4����� ������������+%����������������/1W������+HD'�������������������10�������������K� ���������#�-�?�DE9+/�+HD'�������������/@��M����������������@��M�����@��������@,E2����0�0�5���������������/������$80����!�����4�������4��������� ����������������������+%����������������/1��4���@�1G���0��������������������������������������� !�"������ �!������������������+%����������������/19� �!���@�1G������0����������������!��4�����!�����������������������������������������������������/0���������5���������������4����4��'()*I��4���!�4����� @IIIIIIIIIIIII��������������+HDI.��4�����"����������������+HD93������������������4/+HD93���������0��������-������������()E������4�"+HD93�������/�0���������5�����������4/93���������0-������������+%����������������/1W�III�E�!����������4����IIIW�10��������������������+���2���/0���������5����5��9�������.��5

Die Ausgabe des Beispiels 10.4 ist:

?��!����� ����()�,C9�������������������������� ������F+9D9*2���������+HD'R929E�,/������0���,.��������F������(.��������9E�,:=Z<88�8��;<><<�;Y>=<<<<�8��:;[:>:�:Y�������������������>=<<<<�8��:;[:>:�:Y:L8888�8��Z:><<�8L[;<888�8���Y=<[L�[>��������������+HD'����.� ������9� �!���@�(������2�3��������������� ������4����������������������������+HD'����.� ����������9� �!���@�(������2�3��������������� ������4�������������������+HD'�������������������9� �!���@�:��4���@�C������4������ �������J�����+HD'���������������������4���@�,��I8:Y8:@�9�� ��� ����O������� ��\�����+����

Page 355: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� �""

Im Folgenden werden lediglich die Unterschiede der SQLJ-Realisierung zu der Lösungin Beispiel 10.3 erläutert. Die Namen der gespeicherten Prozeduren und Funktionenwerden in der CREATE PROCEDURE- bzw. CREATE FUNCTION-Anweisung ent-sprechend umbenannt, um Namenskollisionen mit Beispiel 10.3 zu vermeiden. DieKlassennamen wurden ebenfalls angepasst.

Beim Aufruf der ersten Funktion verwenden wir einen positionierten Iterator. Bei die-sem Iterator kann erst nach der FETCH-Anweisung bestimmt werden, ob noch Reihenvorhanden sind oder nicht. Deshalb erfolgt darauf die Abfrage

���/������������4/00�!���

um die Schleife eventuell vorzeitig zu beenden.

Der Aufruf einer gespeicherten Funktion muss in SQLJ in folgender Weise geschehen:

K� ����3��#�-?�DE9+/�+HD'����.� /00�5�

Der Rückgabewert steht vor der geschweiften Klammer und der Funktionsaufruf mussinnerhalb der VALUES-Anweisung stehen.

Weil eine gespeicherte Prozedur generell keine Rückgabewerte liefert, sieht ihr Aufrufanders aus:

�K� ��-�*�DD�+HD'����.� ����/@,E2���3�0�5�

Anstatt der Angabe VALUES wird hier die CALL-Anweisung zum Aufruf verwendet,und in dieser Prozedur benutzter Rückgabewert wird als OUT-Parameter deklariert.(OUT- und INOUT-Parameter müssen immer explizit in der SQLJ-Anweisung angege-ben werden.)

�����8 �� ���������������������� �9��+����������

Trigger sind Mechanismen, die ausgeführt werden, falls die in ihnen enthaltenenBedingungen erfüllt sind. Sie haben grundsätzlich drei Teile:

� den Namen

� die Bedingung

� den Ausführungsteil.

Die Bedingung eines Triggers enthält entweder eine INSERT-, eine UPDATE- oder eineDELETE-Anweisung oder eine Kombination dieser Anweisungen. Der Ausführungs-teil umfasst gewöhnlich mehrere prozedurale und nichtprozedurale SQL-Anweisun-gen.

Page 356: Java in Datenbanksystemen

�"# ������������ ��������� ���������������� �������������������

Bei Oracle werden Trigger mit Hilfe der CREATE TRIGGER-Anweisung erstellt. DieseAnweisung hat folgende Syntax:

*�9�29�2�ARR9����M�������-)9�,�9�Q���29�5�-AB+9�2��E�(�29��(9D9295,B���!M����6�9�9�9B*ABR�6,D(��+����7�6B9O��+���"776�,��9�*P��,O�6OP9BI)���� �� 77���"����� �M��� �

tr_name spezifiziert den Namen des Triggers. tab_name ist der Name der Tabelle, fürdie die Integritätsregel definiert wird.

Die Angaben BEFORE und AFTER kennzeichnen so genannte BEFORE- bzw. AFTER-Trigger (in dieser Reihenfolge). Ein AFTER-Trigger wird aktiviert, nachdem die Trigger-Bedingung erfüllt ist. Ein BEFORE-Trigger wird aktiviert, bevor der Ausführungsteildurchgeführt wird.

Die Angaben INSERT, UPDATE und DELETE stellen die Trigger-Bedingungen dar undspezifizieren die Art der Datenmodifikation, nach der die im Trigger enthalteneAnweisungsfolge ausgeführt wird. Diese drei Angaben können in jeder beliebigenKombination geschrieben werden.

Die Angabe FOR EACH ROW spezifiziert, dass es sich um einen Reihen-Trigger han-delt. Ein solcher Trigger wird aktiviert für jede Reihe, die durch die Anweisungsfolgebetroffen wird.

Die CREATE TRIGGER-Anweisung verwendet zwei spezielle Angabe:

� OLD AS alte_tabelle

� NEW AS neue_tabelle,

die zwei variable Namen (alte_tabelle und neue_tabelle) enthalten. Diese beidenNamen kennzeichnen zwei bei der Ausführung einer CREATE TRIGGER-Anweisungerstellte Tabellen. Ihre Struktur (Tabellenschema) entspricht genau der Struktur derTabelle, für die der Trigger spezifiziert wird. alte_tabelle enthält alle Tabellenreihenmit den ursprünglichen Werten, während neue_tabelle alle Tabellenreihen mit dengeänderten Werten beinhaltet. alte_tabelle und neue_tabelle werden vom Trigger ver-wendet, um zu spezifizieren, wie die Ausführung der Anweisungen innerhalb desTriggers durchgeführt werden soll. (Diese Tabellen können aber selbst nicht durch dieTrigger-Aktion geändert werden.)

Die Tabelle alte_tabelle wird bei der DELETE- und UPDATE-Angabe der CREATETRIGGER-Anweisung, die Tabelle neue_tabelle bei der INSERT- und UPDATE-Angabe verwendet. Für jede INSERT-Anweisung, die für die im Trigger genanntenTabellen ausgeführt wird, wird also anschließend die Tabelle neue_tabelle erstellt.Dementsprechend wird die Tabelle alte_tabelle nach einer entsprechenden DELETE-

Page 357: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� �"$

Anweisung erstellt. Bei einer UPDATE-Anweisung, die für die im Trigger genannteTabelle ausgeführt wird, werden beide Tabellen erstellt: zuerst die Tabelle mit den altenund danach die Tabelle mit den geänderten Werten.

Die Implementierung eines Triggers mit Hilfe der Java-Sprache erfolgt genauso wie dieImplementierung einer gespeicherten Prozedur. Aus diesem Grund werden wir daraufverzichten, die Entwicklungsschritte noch einmal zu erläutern.

Beispiel 10.5 zeigt ein JDBC-Programm, mit dem ein Trigger implementiert wird. Die-ses Beispiel ist eng mit Beispiel 10.6 verzahnt.

Beispiel 10.5

���������� ������!���������'()*2�� ,��-������!��������������������M���������/+���� ���M�������������������������0-����������%�-����������������������?��!����� ��!���������+�������!���������������*��������������#�������������(����.� ��� ��*���������/1��!�@������@����������10�������������+�������������#����������+�������/0�������������+���� �� ��#�1AB+9�2�AB2,�������M����������������������?�DE9+/F1G��M��G1F�E+9��2,M*P��/+]+(�29��F..I((I]]]]�������������[email protected]@++F0�1G��G1�1G���G101�������������������3�����E����/� �0�����������������������/0���������5����4�/+HD93���������0�-5����55

Beispiel 10.6

�������E������������������������������� ������!���������2�� ��M,����-�������������������().+�#�()E�����,��*D9�������!��U�� ���?��!��������()IV� �����������������*��������������#����������������+�������������#����������������������+������#�������������������������������������������������������!�����������������/+���� �� 670����-

ORACLE

ORACLE

Page 358: Java in Datenbanksystemen

�"% ������������ ��������� ���������������� �������������������

����������/�J()E���������(�!��(����/().+00������������������/�/����#�()E������������(�)��/().+00�##�����0������������������%��������-������������+%����������������/1?��!����� ����()�,CW�10������������������#����������+�������/0�������������+%��������������/19���������������������10���������������%-��������������������3�����/1*�9�29�2�)D9�������M����������/��M�����������������*P��/Y0��!��������*P��/:=0�������*P��/L80����������������������M���BE.)9���������M����BE.)9�010�������������5���4/93���������0-5������������������3�����/1*�9�29�,���9�D�*9���,*9(E�9����������������������������/�������4�L��������������������0��������������+�D�BRE�R9�'�?��B�.9�F'()*2�� ,��������M���������/����������������� �+���� ������������0F�10�������������������3�����/1*�9�29�,���9�D�*9�2�ARR9������������������������������29��E�(�29�,���������,B����������,��9�*P��,O�*�DD����������������������������/@������M����@������������@��"�������010�������������+%����������������/1����� �W�10��������������������������!������� �!�������������������2!��/1������M���������10�������������+%����������������/1��4�����@�E�(�29���������+92��������������������#�L88888�OP9�9���M���#�F�LFW�10�������������������3�����/1E�(�29���������+92��������#�L88888�OP9�9���������������M���#�F�LF10��������������������������!������� �!�������������������2!��/1������M���������10����������������!��4�����!������������������������������������������������������/0����������������������/0���������5���������������4����4��'()*I��4���!�4����� @IIIIIIIIIIIII��������������+HDI.��4�����"����������������+HD93������������������4/+HD93���������0��������-������������()E������4�"+HD93�������/�0���������5�����������4/93���������0-������������+%����������������/1W�III�E�!����������4����IIIW�10��������������������+���2���/0���������5����5��9�������.���������+�����"�������� !��������2!���������^!����4������������!�������������������2!��/+���� ��!��0-����������%-���������������#�������3�����H���%/1+9D9*2�����,.�1G�!��0�������������+%����������������/1A�4���2!�����1G�!��0�������������������+��.��(�������#���� ��.��(�/0������������������*�������������������*����#������ ��*�����*����/0�

Page 359: Java in Datenbanksystemen

���������� ����� ������������������� ���������� ����� �"&

���������������/�#:���$#�*������GG0����+������!����4������������������������ �!�����������4��+���������D�������4�����������������������+%��������������/����� ��*�����B��/�0�G��������������()E��������+��/1�1������ ��*�����(����%+���/�0I������������������� ��*�����B��/�0���� �4/0GL�0��0�������������+%����������������/110�������������"4���/�����3�/00������������-�������������������/�#:���$#�*������GG0����O������� �!�����������4���������������������+���������D�������4�����������������������������+%��������������/��� ��,!����/�0�G���������������������()E��������+��/1�1������ ��*�����(����%+���/�0I������������������������ ��,!����/�0���+���� /0���� �4/0GL��00�����������������+%����������������/110�������������5������������+%����������������/110���������5���4/+HD93���������0-������������()E������4�"+HD93�������/�0�������������+%����������������/1��4����!����!�� �������2!�������4����4����10���������5����55

Die Ausgabe des Beispiels 10.6 sieht folgendermaßen aus:

?��!����� ����()�,C9�������������������������� �A�4���2!�����������M�����������MB��)9BE2V9�������V9A2����������.A229DM�D2�������������.A229DMB9E��4�����@�E�(�29���������+92��������#�L88888�OP9�9���M���#�F�LFA�4���2!�����������M�����������MB��)9BE2V9�������V9A2����������.A229DM�D2�������������.A229DMB9E�L����+*,22�����8;I:;IL88:�:<@<[@8=���L88888�����������������L88888

Beispiele 10.5 und 10.6 zeigen, wie Trigger in der Praxis sinnvoll als Kontrollmechanis-men angewendet werden können. In Beispiel 10.6 wird zuerst eine Tabelle (mittel_protokoll), in der alle Änderungen bei den Werten der Projektmittel protokolliert wer-den, erstellt. Die Protokollierung wird anschließend durch den in Beispiel 10.6 definier-ten Trigger durchgeführt.

Jede Änderung der Spalte mittel der Tabelle projekt mit Hilfe der UPDATE-Anwei-sung aktiviert den Trigger. (Diese Anweisung ist in Beispiel 10.6 implementiert.) Beider Aktivierung des Triggers werden den Variablen old.mittel, new.mittel undold.pr_nr aus den erstellten Tabellen old und new die entsprechenden Datenwertezugewiesen. Anschließend werden diese Werte, gemeinsam mit dem Namen desBenutzers, der die UPDATE-Anweisung ausgeführt hat, und der aktuellen Zeit in dieTabelle mittel_protokoll eingefügt.

Page 360: Java in Datenbanksystemen

�#� ������������ ��������� ���������������� �������������������

Die Ausführung der Schritte für die Entwicklung eines Triggers für die Protokollie-rung der Änderungen der Tabelle projekt verläuft in der Praxis in folgender Reihen-folge:

1. Erstellen der Tabelle mittel_protokoll

2. Erstellen des entsprechenden Triggers

3. Testen des Triggers mit Hilfe einer UPDATE-Anweisung

4. Einfügen einer neuen Reihe in die Tabelle mittel_protokoll (durch das Aktivierendes Triggers).

Diese vier Schritte sind in den Beispielen 10.5 und 10.6 nicht in dieser Reihenfolgeimplementiert: Beispiel 10.5 enthält den zweiten Schritt, während Beispiel 10.6 dieanderen Schritte beinhaltet. Wir haben uns für diese Vorgehensweise wegen der Über-sichtlichkeit und der Reduzierung der Programmierumfangs entschieden. (Ein striktesHalten an die oben genannte Reihenfolge würde die Unterteilung des Beispiels 10.6 inmehrere, sehr redundante Programme bedeuten.)

���( �� �!�������������"��!#� ������������������� �:(

Im folgenden Abschnitt wird anhand mehrerer Beispiele die Vorgehensweise zur Erstel-lung und Anwendung von gespeicherten Programmen mit IBM DB2 erläutert. DerAbschnitt wird denselben Aufbau wie der entsprechende Abschnitt bei Oracle haben.Die verwendeten Beispiele sollen die prinzipielle Vorgehensweise aufzeigen, wie solcheProgramme entwickelt werden, damit es jedem möglich ist, gespeicherte Prozedurenund benutzerdefinierte Funktionen mit DB2 zu verwenden und zu verstehen.

Um ein gespeichertes Programm unter DB2 zu implementieren und auf dem Server zuspeichern, sind folgende Schritte notwendig:

1. Implementierung des gespeicherten Programms in einer Java-Klasse

2. Speichern der Klassen in einem Archiv und Übertragen des Archivs auf den Server

�������

IBM DB2 unterscheidet zwischen gespeicherten Prozeduren (stored procedures) undbenutzerdefinierten Funktionen (user defined functions – UDF). Die ersten sind Ser-ver-Routinen, die keinen Rückgabewert haben, während benutzerdefinierte Funk-tionen immer einen Rückgabewert liefern. Im weiteren Verlauf dieses Abschnittswerden wir den übergeordneten Begriff »gespeichertes Programm« verwenden,wenn wir sowohl gespeicherte Prozeduren als auch benutzerdefinierte Funktionenansprechen wollen.

Page 361: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �#�

3. Aktualisieren des gespeicherten Programms im Server

4. Erstellung eines Wrappers

5. Aufruf des gespeicherten Programms.

Die folgenden Abschnitte beschreiben die oben genannten Schritte.

���(�� ��"����� �������������"��!#� ����������

Bei der Implementierung einer gespeicherten Prozedur innerhalb einer Java-Klassemuss man beim IBM DB2 immer folgende Angaben machen:

��!��������������������4��"��93�������

wie z.B.:

��!���������������������������/�+���� �������+���� ��������������������+���� 67������0��4��"��93�������-

Ein Verbindungsobjekt (d.h. eine Instanz der Klasse Connection) muss erzeugt wer-den, falls innerhalb einer gespeicherten Prozedur auf die Datenbank zugegriffen wird.Bei DB2 sieht das so aus:

(����.� ��� ��*���������/1��!�@������@����������10�

Um Werte aus einer gespeicherten Prozedur zurückzuliefern (Parameter vom TypOUT und INOUT), werden Vektoren (Arrays) als Parameter der Prozedur verwendet.Im ersten Element des Vektors werden dann die Rückgabewerte abgelegt.

Die Implementierung einer benutzerdefinierten Funktion sieht anders aus. Um einesolche Funktion zu implementieren existieren zwei Alternativen. Die erste ermöglichtdie Verwendung beliebiger Parameter und Rückgabewerte. Die zu implementierendeKlasse muss die Unterklasse der DB2-Klasse namens UDF sein, die sich im Paket*,.��!���!L������befindet.

Die Methoden, die benutzerdefinierte Funktionen darstellen, müssen mit folgendenAngaben deklariert werden:

��!�������������/���������� !�"���:�6������ !�"���L����70

wobei die letzten Parameter die Rückgabewerte darstellen (siehe z.B. die Deklarationder benutzerdefinierten Funktion getEuro in Beispiel 10.7). Weil die implementierteKlasse eine Unterklasse von UDF ist, erbt sie alle Methoden dieser Oberklasse. Wichtigdabei sind folgende beide Methoden der Klasse UDF:

� isNull()

� set().

Page 362: Java in Datenbanksystemen

�#! ������������ ��������� ���������������� �������������������

Die Methode isNull() wird benutzt, um einen bestimmten Parameter auf den SQL-NULL-Wert zu überprüfen. Die set()-Methode hingegen ist dafür zuständig, die Rück-gabewerte zuzuweisen. Um beispielsweise dem letzten Parameter einer Funktion mit 4Parametern den Rückgabewert zuzuweisen, würde man

���/Y����0

angeben, wobei value ein zum Parameter kompatibler Typ sein muss. (Bei derCREATE FUNCTION-Anweisung muss hierbei PARAMETER STYLE DB2GENERALangegeben werden.)

Bei der zweiten Alternative muss die Deklaration einer benutzerdefinierten Funktionfolgende Angaben enthalten:

��!�������������� !�"����������������/������������0

Die zu implementierende Klasse wird dabei nicht von der Klasse UDF abgeleitet, unddie Rückgabewerte werden (wie üblich) mit Hilfe der return-Anweisung zurückgelie-fert. Bei dieser Alternative können allerdings keine Strukturen übergeben bzw. zurück-gegeben werden. (Bei der CREATE FUNCTION-Anweisung muss in diesem FallPARAMETER STYLE JAVA angegeben werden.)

���(�( "��!#������)����������������*!#�������;�� ��������+ ��� ���

Da ein gespeichertes Programm manchmal aus mehreren Klassen bestehen kann, emp-fiehlt es sich, alle zugehörigen Klassen in ein Archiv zu speichern. Das dabei erstellteArchiv muss auf den Server in das Verzeichnis <DB2-DIR>/functions übertragen wer-den, damit der Server darauf zugreifen kann. (DB2-DIR kennzeichnet das Dateiver-zeichnis, in dem DB2-Dateien installiert werden.) Das Dateiverzeichnis <DB2-DIR>/functions kann auch verwendet werden, um Klassen eines Pakets abzulegen.

Serverseitig kann bei SQLJ auf dem Datenbank-Server die Registrierung über:

�!L����� ���������M��/F����@�@WW��"�����WW+HD'+�()L���F��F+HD'+�()LF0

vorgenommen werden. Die Datei wird dann in:

���������W��W$��4�����I���I� ���������I!��������&W+HD'+�()L

abgelegt. Damit gibt es zwei Alternativen, wie und wo die Dateien abgelegt werden.Bei der ersten Alternative (in <DB2-DIR>/functions) können alle Benutzer auf diegespeicherte Datei zugreifen, während bei der zweiten nur der Benutzer, der denZugriff auf das entsprechende Schema hat, die Datei verwenden kann.

Page 363: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �#�

���(�, *� �����������������"��!#� ����������

Da der Server gewöhnlich eine einmal geladene Java-Klasse bis zum Neustart im Spei-cher behält, muss bei einer Änderung eines gespeicherten Programms der Server infor-miert werden, damit die modifizierten Klassen verwendet werden können. DieseAktualisierung geschieht mit Hilfe der SQL-Anweisung

*�DD�+HD'��9��9+PM*D�++9+/0

für alle mit der FENCED-Angabe deklarierten Funktionen. (Die Angabe FENCEDwird im nächsten Schritt erläutert.)

Falls in der CREATE PROCEDURE- bzw. CREATE FUNCTION-Anweisung dieAngabe NOT FENCED verwendet wird, muss man den Server neu starten, um dieAktualisierung wirksam zu machen.

���(�- �� �������������2�""��

Der nächste Schritt zeigt die Erstellung eines SQL-Wrappers. (Ein SQL-Wrapper kenn-zeichnet ein SQL-Skript, das ein Java-Programm für den Datenbank-Server so transfor-miert, dass dieses dem Server als ein in SQL geschriebenes gespeichertes Programmerscheint.) Eine gespeicherte Prozedur wird mit Hilfe der CREATE PROCEDURE-Anweisung erstellt, während die CREATE FUNCTION-Anweisung eine benutzerdefi-nierte Funktion erzeugt.

Wir werden als Beispiel die Erstellung der gespeicherten Prozedur testMsg nehmen,um die CREATE PROCEDURE-Anweisung zu erörtern:

*�9�29���,*9(E�9�29+2.+R/,E2��� �*P��/ZY0�0�D�BRE�R9�'�?������.929��+2]D9�'�?���9B*9(�.,(A�A9+�+HD�(�2��9_29�B�D�B�.9�F'()*+�()L�����.� F

Wie aus dem Beispiel mit der CREATE PROCEDURE-Anweisung ersichtlich, verlangtdiese Anweisung nach dem Prozedurnamen, dem Modus, Namen und SQL-Daten-typen jedes Parameters, der externen Position der Funktion sowie dem Parameterstil.

Nach den Schlüsselwörtern CREATE PROCEDURE kommt der Name der gespeicher-ten Prozedur. Danach folgt die Definition der einzelnen Parameter mit deren Typ (undLänge) sowie, ob es sich um Ein- oder Ausgabeparameter handelt (OUT, IN oderINOUT).

Die Option LANGUAGE JAVA gibt an, dass die Funktion in Java implementiertwurde, während die Option PARAMETER STYLE JAVA Java-Parameterübergabe defi-niert. (Die alternative Angabe zu PARAMETER STYLE JAVA heißt PARAMETERSTYLE DB2GENERAL und ermöglicht die Benutzung beliebiger Parameter und Rück-gabewerte.) Die Angabe FENCED gibt an, dass für jeden Aufruf eine eigene JVM ver-wendet werden soll. Eine Alternative dazu stellt NOT FENCED dar, die eine

Page 364: Java in Datenbanksystemen

�#� ������������ ��������� ���������������� �������������������

Aktualisierung der gespeicherten Prozeduren erst nach einem Neustart des Serversermöglicht. MODIFIES SQL DATA erlaubt die Verwendung sämtlicher in einer gespei-cherten Prozedur erlaubten SQL-Anweisungen. EXTERNAL NAME schließlich gibtdie Position dieser Prozedur in einer Java-Klasse an. In diesem Fall handelt es sich umdie Klasse JDBCSrvDB2 mit der Methode testMsg. (Ein Archiv kann davor, mit Dop-pelpunkt getrennt, angegeben werden.)

Die Syntax der CREATE FUNCTION-Anweisung sieht ein wenig anders aus. Nach derDefinition der Rückgabewerte wird über die Angabe RETURNS <typ> der Rückgabe-wert der Funktion definiert. Die Angabe NO SQL muss angegeben werden, da inner-halb einer benutzerdefinierten Funktion keine SQL-Anweisungen ausgeführt werdendürfen. Folgende Anweisung verdeutlicht die Erstellung einer benutzerdefiniertenFunktion:

*�9�29��EB*2A,B�R929E�,/������D,�2�0��92E�B+��D,�2�B,�+HD��9B*9(�D�BRE�R9�'�?������.929��+2]D9�()LR9B9��D�9_29�B�D�B�.9�T'()*+�()L� ��9���T

���(�. *�+�+��������"��!#� ����������

Sind all diese Schritte erfolgreich abgeschlossen, kann nun der Aufruf des gespeicher-ten Programms von einer Java-Anwendung erfolgen. Beispiel 10.7 zeigt eine Java-Klasse namens JDBCSrvDB2, die mehrere gespeicherte Prozeduren und benutzerdefi-nierte Funktionen enthält.

Beispiel 10.7

���������� �����������*,.��!���!L��������!���������'()*+�()L��3������E(�-����!������������������.� /+���� 67��� 0��4��"��93�������-���������� 687�#�1(������2�3��������������� ������4��������������1���5�����E(�I�������������������!�������.929��+2]D9�()LR9B9��D����������@���!�������������/�����$������I�%��&0����!�������� ��9���/���!�����������!���������0��4��"��93�������-�����������/L�����:�;<<=>80���5�����E(����������.929��+2]D9�'�?�@

�������

Das oben angegebene Beispiel kann also als Muster für die Erstellung von gespei-cherten Prozeduren verwendet werden. Lediglich eine Änderung von Prozedurna-men, Parametern und externer Position ist dazu noch erforderlich.

DB2

Page 365: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �#"

�����4����������3������E(���U�� ����!�������������!��� ��9���L/���!������0-���������������/����:�;<<=>80���5����!���������������������������/�+���� �������+���� �����������������������+���� 67������0��4��"��93�������-�������������#8���������%�-������������������?��!����� ��!���������+�������!�����������*��������������#���������(����.� ��� ��*���������/1��!�@������@����������10���������+���� �� ��#�1AB+9�2�AB2,���,'9C2�?�DE9+�/�F1�G������G�1F����������F1�G�������G�1F��1�G��������G�101���������+�������������#����������+�������/0�������������#�������3�����E����/� �0�������������������/0�������5����4�/+HD93���������0�-�������������687#�� ��.��� �/0���������������������5���������687#1:����4����� ��� �1��������������55

Da die Klasse auch eine benutzerdefinierte Funktion (getEuro) enthält, wird sie vonder Oberklasse UDF abgeleitet und das entsprechende Paket mit Hilfe von:

�������*,.��!���!L�����

in das Programm eingebunden.

Beispiel 10.7 enthält zwei benutzerdefinierte Funktionen und zwei gespeicherte Proze-duren. Die benutzerdefinierte Funktion getEuro wurde nach der ersten Alternativeimplementiert. (Für die Beschreibung der beiden Alternativen siehe den Abschnitt»Implementierung der gespeicherten Programme« in diesem Kapitel.) Aus diesemGrund existiert in ihrer Deklaration:

��9���/���!�����������!���������0

ein Rückgabeparameter namens result, der als letzter in der Parameterliste angegebenund mit der Anweisung

���/L�����:�;<<=>80�

zugewiesen wird. Weil getEuro nach der ersten Alternative für die Implementierungder benutzerdefinierten Funktionen programmiert wurde, muss in der CREATEFUNCTION-Anweisung die Angabe PARAMETER STYLE DB2GENERAL verwendetwerden.

Page 366: Java in Datenbanksystemen

�## ������������ ��������� ���������������� �������������������

Die benutzerdefinierte Funktion getEuro2 wurde nach der zweiten Alternative imple-mentiert. Aus diesem Grund braucht diese Funktion die Klasse UDF nicht als Ober-klasse. Die Registrierung dieser Funktion erfolgt mit Hilfe der PARAMETER STYLEJAVA-Angabe in der CREATE FUNCTION-Anweisung.

Die gespeicherte Prozedur testMsg stellt ein sehr einfaches Datenbankobjekt dar, daslediglich eine Zeichenkette ausgibt. Für die Rückgabe des Ausgabewertes wird einVektor mit String-Elementen verwendet, dessen erstes Element die Zeichenkette zuge-wiesen bekommt. Auf diese Art und Weise könnte z.B. eine Ergebnismenge zurückge-geben werden.

Die etwas komplexere Prozedur insertProjekt fügt eine neue Zeile mit Inhalt in dieTabelle projekt ein. Damit eine Verbindung zur Datenbank erstellt werden kann, mussfolgende interne Treiberverbindung benutzt werden:

��!�@������@����������

Beispiel 10.8 zeigt, wie man mit Hilfe von JDBC gespeicherte Programme in der Daten-bank registriert und aufruft.

Beispiel 10.8

�������E������������������������������� ������!���������'()*M*�����M()L-�������������������().+�#�()E�����()L�������!��U�� ���?��!��������()IV� �����������������*��������������#����������������+�������������#����������������������+������#�������������������������������������������������������!�����������������/+���� �� 670����-����������/�J()E���������(�!��(����/().+00������������������/�/����#�()E������������(�)��/().+00�##�����0������������������%��������-������������+%����������������/1?��!����� ����()�,CW�10������������������#����������+�������/0�������������+%��������������/19���������������������10���������������%-����������������������3�����E����/1(�,����,*9(E�9�����������������29+2.+R/*P��/ZY0010�������������5���4/93���������0-5��������������%-

DB2

Page 367: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �#$

����������������������3�����E����/1(�,���EB*2A,B�R929E�,/�D,�2010�������������5���4/93���������0-5��������������%-����������������������3�����E����/1(�,����,*9(E�9�����������������AB+9�2��,'9C2/*P��/Y0��*P��/L<0���9�D���*P��/L<80010�������������5���4/93���������0-5�������������� �`���������������������+�������������������@������������������3�����/1*�DD�+HD'��9��9+PM*D�++9+/010���������������E(�����()��� ������������������������!������4�I���������������(����%������������ !�"������������������'I+�%��@��������������������3�����/1*�9�29��EB*2A,B�R929E�,/������D,�2�0������������������92E�B+��D,�2�B,�+HD��9B*9(�����������������D�BRE�R9�'�?������.929��+2]D9�'�?��9_29�B�D�B�.9�����������������F'()*+�()L� ��9���LFa0����������������!����3������E(���������+������������������ !�"���������������������������������@������������������3�����/1*�9�29��EB*2A,B�R929E�,/������D,�2�0��������������92E�B+��D,�2�B,�+HD��9B*9(������������D�BRE�R9�'�?������.929��+2]D9�()LR9B9��D�������������9_29�B�D�B�.9�F'()*+�()L� ��9���F10���������������+�����()��� ���������������������������3�����/1*�9�29���,*9(E�9�29+2.+R/�,E2��� �*P��/ZY0�������������0�D�BRE�R9�'�?������.929��+2]D9�'�?���9B*9(������������.,(A�A9+�+HD�(�2��9_29�B�D�B�.9�������������F'()*+�()L�����.� F10�������������������3�����/1*�9�29���,*9(E�9�AB+9�2��,'9C2/�AB������������������*P��/Y0��AB�������*P��/L<0��AB���������9�D��������������,E2�������*P��/L<80�0�D�BRE�R9�'�?������.929��������������+2]D9�'�?���9B*9(�.,(A�A9+�+HD�(�2��9_29�B�D�B�.9�������������F'()*+�()L��������������F10�������������+%����������������/1����� �W�10�����������������������������E(�@������������+%����������������/1�����F+9D9*2���������R929E�,/������0���������������,.��������F������10�������������������+������#�������3�����H���%/1+9D9*2���������������������R929E�,/������0���,.��������10�������������+%����������������/1(.W�W�9E�,10�������������"4���/�����3�/00����������������+%����������������/��� ������/:0G�1��W�1�G������������������� ������/L00���������������IIIIIIIIIIIIIIIIII��������������������������+���������������������������+%����������������/1W�������������������.� ������10�������������*��!��+�������������#����������*��/1*�DD�������������29+2.+R/X010���������������������*���������� ���4�������� ��������������()E������4�"O���� �/������ ��O���� �/00��������������������� �����,���������/:��2%����*P��0�����������������������������4����������������������3�����/0�

Page 368: Java in Datenbanksystemen

�#% ������������ ��������� ���������������� �������������������

������������+���� ���3��#������� ��+���� /:0�������������+%����������������/19� �!���@�1G��3�0����������������?��!���������������*�������������@������������+���� ���M���#�1�>1�������������+���� ���M����#�1?����1�������������������������#�>=<<<<�������������������#�����������*��/1*�DD�AB+9�2��,'9C2/�X���X���X���������������X0�10���������������������*���������� ���4�������� ��������������()E������4�"O���� �/������ ��O���� �/00�������������������� !�"������������������������������������� �����,���������/L��2%����AB29R9�0��������������������� �����,���������/Y��2%����*P��0��������������������������"��������������������������+���� /:���M��0����������������������+���� /L���M���0��������������������������/>�������0�����������������������������4���������������+%����������������/1W�������������������������10��������������������3�����/0�������������������� !�"����������������������+���� �����#������� ��+���� /Y0�������������+%����������������/19� �!���@�1G���0��������������������������"��������������������������+���� /:�1F10����������������������+���� /L�1�����10��������������������������/>�<888880�����������������������������4����������U ���4�����4���!�4����� ������������+%����������������/1W�������������������������10��������������������3�����/0�������������+%����������������/19� �!���@�1G������ ��+���� /Y00����������������!��4�����!�������������������������������������������������������/0����������������������/0���������5���������������4����4��'()*I��4���!�4����� @IIIIIIIIIIIII��������������+HDI.��4�����"����������������+HD93������������������4/+HD93���������0��������-������������()E������4�"+HD93�������/�0���������5�����������4/93���������0-������������+%����������������/1W�III�E�!����������4����IIIW�10��������������������+���2���/0���������5����5��9�������.��5

Page 369: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �#&

Die Ausgabe des Beispiels 10.8 ist:

?��!����� ����()�,C9�������������������������� ������F+9D9*2���������R929E�,/������0���,.��������F������(.��������9E�,:L8888�8��Z:><<�8L[;<888�8���Y=<[L�[>:=Z<88�8��;<><<�;Y������������������.� ������9� �!���@�(������2�3��������������� ������4��������������������������������������9� �!���@�:����4����� ��� �������������������������������������������������4���@�6A).76*DA�(����76()L�B27�+HD88:8B��(�������1F��<88888�801�!� ��������V���4����� ����������4��������!��4����!� ������ �����4�����+HD+2�29#YLZ8>����

Zuerst werden eventuell bereits vorhandene Datenbankobjekte, die anschließenderstellt werden, von dem Datenbank-Server entfernt. Dazu ist es wichtig, den Namenund die Parameterleiste exakt wie bei der Deklaration anzugeben.

Mit Hilfe von

*�DD�+HD'��9��9+PM*D�++9+/0

werden aktualisierte Datenbankobjekte dem Server mitgeteilt und beim nächsten Pro-zeduraufruf neu instantiiert.

Danach werden die gespeicherten Programme registriert. Der Aufruf einer benutzer-definierten Funktion kann innerhalb einer SQL-Anweisung (z.B. SELECT) stattfinden,um so eine komplexe Anweisung mit erweiterter Logik auszuführen. Der Aufruf einergespeicherten Prozedur erfolgt mit Hilfe der CALL-Anweisung. Die Angabe ihrerParameter wird innerhalb einer Instanz der Klasse CallableStatement durchgeführt,wobei das Zeichen »?« als Platzhalter für den entsprechenden Parameter verwendetwird. Die set()/get()-Methoden weisen diesen Parametern dann die Werte zu, bzw.ermöglichen das Auslesen der Werte. Der Aufruf der gespeicherten Prozedur insert-Projekt zeigt, wie man Parameter übergibt und den Rückgabewert ausliest.

���(�1 <��"��!#� ��������������%=�

Die Entwicklung eines gespeicherten Programms kann bei IBM DB2 auch mit SQLJdurchgeführt werden. In diesem Fall werden dieselben fünf Schritte ausgeführt, dieam Anfang des Abschnitts 10.2 aufgelistet sind. Die Beschreibung dieser Schritte giltmit kleinen Ausnahmen auch für SQLJ. Im Folgenden werden die Unterschiede erläu-tert.

Der erste Schritt – Implementierung eines gespeicherten Programms – erfordert ledig-lich, dass die .sqlj-Dateien zusätzlich mit dem Vorübersetzer vorübersetzt werden. Bei

Page 370: Java in Datenbanksystemen

�$� ������������ ��������� ���������������� �������������������

der Speicherung der Klassen in einem Archiv ist darauf zu achten, dass auch dieDateien mit .ser-Endung, falls existent, mit in das Archiv aufgenommen werden. Dazumuss das jar-Kommando um die entsprechende Endung erweitert werden:

���I��8�$���4����&����$+�IC�����&�������$+�IC�����&�����

Die Übertragung der Dateien auf den Server weist ebenso kleine Unterschiede auf. DieDateien werden hier entweder in das Verzeichnis <DB2-DIR>/functions/jar/<SCHE-MANAME>/ kopiert oder über die Anweisung

��!L������ ���������M��/T����@$ �����&�T$����&T0

in einem Fenster am Server eingegeben. Folgendes Beispiel zeigt die Verwendung derreplace_jar()-Methode:

�!L������ ���������M��/F����@�@WW��"�����WW+HD'+�()L���F�F+HD'+�()LF0

Die folgenden Beispiele zeigen die Realisierung der in den Beispielen 10.7 und 10.8dargestellten gespeicherten Programme mit SQLJ. Dabei entspricht Beispiel 10.9logisch dem Beispiel 10.7 und Beispiel 10.10 dem Beispiel 10.8.

Beispiel 10.9

��!���������+HD'+�()L��3������E(�-����!������������������.� /+���� 67��� 0��4��"��93�������-���������� 687�#�1(������2�3��������������� ������4��������������1���5�����E(�I�������������������!�������.929��+2]D9�()LR9B9��D����������@���!�������������/�����$������I�%��&0����!�������� ��9���/���!�����������!���������0��4��"��93�������-�����������/L�����:�;<<=>80���5�����E(����������.929��+2]D9�'�?�@�����4����������3������E(���U�� ����!�������������!��� ��9���L/���!������0-���������������/����:�;<<=>80���5�����!���������������������������/�+���� �������+���� ������������������������+���� 67������0��4��"��+HD93�������-�����������#8�������%�-��������K� ��-�AB+9�2�AB2,���,'9C2�?�DE9+/�@�����@������@������05�����5���4�/93���������0�-������������������4����!�� �������*������������ �!���������������687#�� ��.��� �/0��������������������5���������687#1:����4����� ��� �1�

DB2

Page 371: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �$�

�������������55

Der einzige nennenswerte Unterschied zu Beispiel 10.7 ist, dass für die existierendenSQL-Anweisungen keine explizite Verbindung eröffnet werden muss, da diese auto-matisch bereits vorhanden ist. Es sind also lediglich SQL-Anweisungen anzugebenund keine weiteren Vorbereitungen nötig.

Beispiel 10.10

�������E������������������������������� ������������ ���������������(�����*����3����!���������+HD'M*�����M()L-�������������������().+�#�()E�����()L�������!��U�� ���?��!��������()IV� �����������������*��������������#��������������������������������������������������������B����A����������K� ����!������������������A����/����������0�������!�����������������/+���� �� 670����-����������/�J()E���������(�!��(����/().+00������������������/�/����#�()E������������(�)��/().+00�##�����0������������������%��������-������������(�����*����3�����(�����*����3�/��"�������������(�����*����3�/���00�������������+%����������������/1?��!����� ����()�,CW�10�

������������+%��������������/19���������������������10���������������%-����������������K� ��-�(�,����,*9(E�9�+HD'29+2.+R/*P��/ZY00�5�������������5���4/93���������0-5��������������%-����������������K� ��-�(�,���EB*2A,B�+HD'R929E�,/�D,�20�5�������������5���4/93���������0-5��������������%-����������������K� ��-�(�,����,*9(E�9�+HD'AB+9�2��,'9C2/*P��/Y0������������������*P��/L<0���9�D���*P��/L<800�5�������������5���4/93���������0-5�������������� �`���������������������+�������������������@������������K� ��-�*�DD�+HD'��9��9+PM*D�++9+/0�5���������������E(�����()��� ������������������������!������4�I���������������(����%������������ !�"������������������'I+�%��@

DB2

Page 372: Java in Datenbanksystemen

�$! ������������ ��������� ���������������� �������������������

��������������K� ��-�*�9�29��EB*2A,B�+HD'R929E�,/������D,�2�0��������������������92E�B+��D,�2�B,�+HD��9B*9(�D�BRE�R9�'�?������������������������.929��+2]D9�'�?��9_29�B�D�B�.9�������������������F+HD'+�()L� ��9���LF�5����������������!����3������E(���������+������������������ !�"���������������������������������@������������K� ��-�*�9�29��EB*2A,B�+HD'R929E�,/������D,�2�0��������������������92E�B+��D,�2�B,�+HD��9B*9(�������������������D�BRE�R9�'�?������.929��+2]D9�()LR9B9��D�9_29�B�D�������������������B�.9�F+HD'+�()L� ��9���F�5���������������+�����()��� ���������������������K� ��-�*�9�29���,*9(E�9�+HD'29+2.+R/�,E2��� �*P��/ZY0�0�������������D�BRE�R9�'�?������.929��+2]D9�'�?���9B*9(�������������������.,(A�A9+�+HD�(�2��9_29�B�D�B�.9�������������������F+HD'+�()L�����.� F�5�������������K� ��-�*�9�29���,*9(E�9�+HD'AB+9�2��,'9C2/�AB������������������������*P��/Y0��AB�������*P��/L<0��AB���������9�D��������������������,E2�������*P��/L<800�D�BRE�R9�'�?������������������������.929��+2]D9�'�?���9B*9(�.,(A�A9+�+HD�(�2��������������������9_29�B�D�B�.9�F+HD'+�()L��������������F�5�������������+%����������������/1����� �W�10�����������������������������E(�@������������+%����������������/1�����F+9D9*2���������������������+HD'R929E�,/������0���,.��������F������10�������������A���������������������K� �������#�-�+9D9*2���������+HD'R929E�,/������0���,.���������������������5�������������+%����������������/1(.W�W�9E�,10�������������������������#����������#�����������������"4����/����0�-�������������������K� ��-��92*P�@�����AB2,�@���������@�����5�����������������������/������������4/00�!�����������������������+%����������������/�������G�1��W�1G�����0�������������5����������������������/0���������������IIIIIIIIIIIIIIIIII������������+%����������������/1W���������������+HD'����.� �����10�������������+���� ���3��#�11�������������K� ��-�*�DD�+HD'����.� /@,E2���3�0�5�������������+%����������������/19� �!���@�1G��3�0����������������?��!��������P����3��������������������@������������+���� ���M���#�1�>1�������������+���� ���M����#�1?����1�������������������������#�>=<<<<�������������+���� �����#�11�������������+%����������������/1W������+HD'�������������������10�������������K� ��-�*�DD�+HD'�������������/@��M����@��M�����@��������������������@,E2����0�5�������������+%����������������/19� �!���@�1G���0��������������������������"�������������������M���#�1�������:L1�

Page 373: Java in Datenbanksystemen

���������� ����� ������������������� ���������� �'! �$�

��������������M����#�1�����1��������������������#�<88888�����������������������������4����������U ���4�����4���!�4����� ������������+%����������������/1W������+HD'�������������������10���������������%-����������������K� ��-�*�DD�+HD'�������������/@��M����@��M���������������������@��������@,E2����0�5�����������������+%����������������/19� �!���@�1G���0�������������5���4/+HD93���������0������������-����������������()E������4�"+HD93�������/�0�������������5���������������!��4�����!�����������������������������������������������������/0���������5���������������4����4��'()*I��4���!�4����� @IIIIIIIIIIIII��������������+HDI.��4�����"����������������+HD93������������������4/+HD93���������0��������-������������()E������4�"+HD93�������/�0���������5�����������4/93���������0-������������+%����������������/1W�III�E�!����������4����IIIW�10��������������������+���2���/0���������5����5��9�������.��5

Die Ausgabe des Beispiels 10.10 ist:

?��!����� ����()�,C9�������������������������� ������F+9D9*2���������+HD'R929E�,/������0���,.��������F������(.��������9E�,:L8888�8��Z:><<�8L[;<888�8���Y=<[L�[>:=Z<88�8��;<><<�;Y>=<<<<�8��:;[:>:�:Y��������������+HD'����.� ������9� �!���@�(������2�3��������������� ������4�������������������+HD'�������������������9� �!���@�:����4����� ��� ����������������������������������+HD'�������������������III�+HD93����������� ��������III��4��������� �@�����6A).76*DA�(����7�*DA8:8;9��V���4����� �����4���! ���4��������+HD+2�29#LL88:_,�9BI��4��������@��LL88:P���������I*����@���I;;;;;

Page 374: Java in Datenbanksystemen

�$� ������������ ��������� ���������������� �������������������

In Beispiel 10.10 werden alle SQL-Anweisungen über SQLJ ausgeführt. Damit keineÜberschneidung mit Beispiel 10.8 auftritt, werden die erstellten benutzerdefiniertenFunktionen und gespeicherten Prozeduren umbenannt und bei der Registrierung einanderer Name für die Server-Klasse gewählt.

Weil Beispiel 10.10 dem Beispiel 10.8 sehr ähnlich ist, werden wir hier nur auf dieUnterschiede hinweisen: Bei der Verwendung einer Funktion in der SELECT-Anwei-sung benutzen wir einen positionierten Iterator, um den Wert der benutzerdefiniertenFunktion lesen zu können. Die Abfrage, ob noch Reihen vorhanden sind, sollte nachder FETCH-Anweisung und vor dem Zugriff auf das erste Element erfolgen. Aus die-sem Grund existiert im Programm folgende Anweisung:

���/������������4/00�!����

Beim Aufruf einer gespeicherten Prozedur muss jeweils angegeben werden, ob es sichum eine OUT-Variable handelt, wie z.B.:

*�DD�+HD'�������������/@��M����@��M�����@��������@,E2����0

(In diesem Beispiel ist der letzte Parameter ein Rückgabewert.)

���, >�������+������

Der wichtigste Vorteil der Verwendung der Java-Sprache für die Implementierung vonserverseitigen Datenbankobjekten wie Prozeduren und Triggern liegt in der Vereinheit-lichung der Implementierung. Das heißt, dass für alle existierenden Datenbank-systeme eine einheitliche Schnittstelle (die Java-Sprache eben) verwendet werdenkann, um Objekte zu entwickeln.

In der Praxis sieht es so aus, dass noch immer zu große Unterschiede bei den verschie-denen Datenbanksystemen (besonders in den Entwicklungsschritten) existieren, umein serverseitiges Datenbankobjekt zu entwickeln, welches ohne Portierung auf allenSystemen lauffähig ist.

Das nächste Kapitel ist das Anfangskapitel des letzten Teils des Buches. Es beschreibtdas Java-Datenbanksystem namens Cloudscape.

Page 375: Java in Datenbanksystemen

����������� �������� ���

Page 376: Java in Datenbanksystemen
Page 377: Java in Datenbanksystemen

�� ���������

In den letzten Jahren wurde die Java-Sprache immer mehr als Sprache für die System-programmierung benutzt. Eines der Gebiete, wo sie als Programmiersprache für dieImplementierung großer Systeme eingesetzt wurde, war die Implementierung vonDatenbank-Servern. Seit etwa 1996 sind auf dem Markt mehrere Datenbanksystemeerschienen, deren Server ausschließlich in der Java-Sprache implementiert sind.

Die auf dem Markt befindlichen Java-Datenbanksysteme können in kommerzielle undopen source-Software unterteilt werden. Zu der ersten Gruppe gehören u.a.:

� Cloudscape (www.cloudscape.com)

� PointBase (www.pointbase.com)

� Jeevan (www.jeevan.com)

während

� Ozone (http://ozone.db.org/ozone_main.html)

� InstantDB (http://instantdb.enhydra.org)

zu den open source-Java-Dataenbanksystemen gehören.

In diesem Teil des Buches werden die ersten beiden kommerziellen Produkte beschrie-ben: Cloudscape in diesem und PointBase im nächsten Kapitel.

���� �� ����������������� ��������������

Cloudscape ist ein in der Java-Sprache implementiertes Datenbankmanagement-system, welches ursprünglich von der gleichnamigen Firma entwickelt wurde. DieseFirma wurde von ehemaligen Mitarbeitern von Informix, Oracle und Sybase im Juni1996 gegründet.

Ursprünglich wollte Cloudscape den Markt für kleine, herunterladbare und plattform-unabhängige Datenbanksysteme beliefern. Vergleichbare Datenbanksysteme warendamals zwar in Form von Oracle Lite der Firma Oracle und SQL Anywhere der FirmaSybase vorhanden, waren aber nicht in der Java-Sprache implementiert.

Page 378: Java in Datenbanksystemen

��� ����������� ��

Die erste Version von Cloudscape erschien nach zweijähriger Entwicklungszeit imMärz 1998, Version 2.0 ein Jahr darauf. Im 1998 wurde das Produkt als »Datenbank desJahres« von den Zeitschriften JavaWorld und Java Developer’s Journal geehrt. Im Septem-ber 1999 wurde Cloudscape dann von Informix für 85 Milionen Dollar aufgekauft. MitCloudscape wollte Informix im mobilen Datenbanksegment ein Produkt haben, indem Oracle, Sybase, IBM und Microsoft bereits Fuß gefasst hatten.

Durch die Übernahme der Firma Informix von IBM im April 2001 wurde Cloudscapeein IBM-Produkt. Zum Zeitpunkt des Schreibens dieses Buches ist es noch nicht klar,was mit diesem Datenbanksystem passieren wird. Es gibt einige Indizien dafür, dassdas Produkt allen Interessenten kostenlos zur Verfügung gestellt wird.

Die wichtigsten Eigenschaften von Cloudscape sind:

� keine Administrierung notwendig

� Unterstützung verteilter Umgebungen

� Unterstützung objektorientierter Konzepte

� wenig Speicherbedarf beim Laden (small footprint)

� läuft mit jeder (zertifizierten) JVM.

Cloudscape ist ein benutzerfreundliches Datenbanksystem, weil (fast) alle Administra-tionsaufgaben, die bei den anderen Datenbanksystemen der Datenbank- bzw. System-administrator machen muss, automatisch vom System durchgeführt werden.

Seit Version 2.0 enthält Cloudscape eine patentierte Synchronisations-Technologienamens LUCID (Logic Up Consistent Information Down), die Konfliktbehebung ohneProgrammieraufwand ermöglicht und sicherstellt, dass zwischen laufenden und ver-teilten Anwendungen Konsistenz besteht. Als objektrelationales Datenbanksystemkann Cloudscape nicht nur relationale Daten, sondern auch Objekte verarbeiten.

Fast jeder Datenbankhersteller hat ein Produkt, das für mobile Rechner implementiertist. Die Eigenschaft solcher Systeme ist, dass sie sehr wenig Speicherbedarf beim eige-nen Laden brauchen. Diese Eigenschaft wird mit small footprint bezeichnet. Eine derwichtigsten Vorgaben für Cloudscape war, dass das Produkt auf sehr kleinen Rechnernlaufen muss. Aus diesem Grund braucht das Produkt nur etwa 2 MB Speicherplatz,um geladen zu werden.

�������

Die aktuelle Version ist 3.6.

Page 379: Java in Datenbanksystemen

����� ��� ������������ ���� ������� ���

Durch die hundertprozentige Implementierung in der Sprache Java ist zwar einerseitseine Java Virtual Machine (JVM) auf dem System erforderlich, andererseits ist dadurchdie Plattformunabhängigkeit garantiert. Damit kann Cloudscape mit nahezu jedemBrowser ausgeführt werden.

��� ���������������!�� "�� ��������#$

Als objektrelationales Datenbanksystem (ORDBMS) können in Cloudscape nicht nurStandarddatentypen (wie z.B. INT, CHAR und DATE) verwendet werden, sondernauch Objekte wie Bilder oder auch benutzerdefinierte Java-Objekte.

So können beispielsweise in einer Tabelle Spalten, deren Datentyp eine Java-Klasse ist,angelegt werden und die Methoden, die von der Klasse implementiert sind, könnendirekt in einer SQL-Anweisung angesprochen werden. Dies ermöglicht einen fließen-den Übergang zwischen Geschäfts- und Datenlogik, da beide die gleiche Sicht auf dieDaten haben und die Datenbank so aussieht, als wäre sie speziell für die aktuelleAnwendung geschrieben. (Für die Beschreibung der Geschäfts- und Datenlogik sieheKapitel 4.) Die Objektdaten können also auch ein Verhalten speichern, da dieses durchdie jeweilige Implementierung eines benutzerdefinierten Objektes vorgegeben werdenkann. (In objektorientierter Programmierung werden Daten nicht von der zugehörigenLogik getrennt).

Beispiele 11.1 und 11.2 zeigen wie Java-Klassen als Datentypen einer Tabellenspalteverwendet werden können.

Beispiel 11.1

������������� ������������������������������������������������������������������������������������������������������������ ����������������������������!�������������������� ������������������ ����������������� ��������� ������"����������#�������������#����������$!�������������%����

�������

Falls ein Java-Objekt verwendet wird, muss es serialisierbar sein. Objekt-Serialisie-rung heißt, dass die Instanz einer Klasse die Java Schnittstelle Serializable imple-mentiert und dadurch in eine Byte-Sequenz umgewandelt wird, die anschließendwieder zur ursprünglichen Instanz zurückgewandelt werden kann. Mit diesemVerfahren lässt sich eine Art Persistenz für Objekte erreichen.

Page 380: Java in Datenbanksystemen

��� ����������� ��

���������������%������ ���������������%������ ��&����������������'����"$!������������� �&�������������������(��"$!����������� �&������������������� ����"$!������������� �&�������������������)���� ����"$!������������������� �&������������������������"$!�����������* �������*+���+*� ����,�*+-��������������"�����$+*�'����,�*+.���������������"�����$+*/�* ��&&

Beispiel 11.1 zeigt die Erstellung einer Java-Klasse namens Produkt, die in Beispiel 11.2als benutzerdefinierter Datentyp für die Definition einer Tabellenspalte verwendetwird. Diese Klasse muss mit der Angabe implements Serializable definiert werden,weil sie dauerhaft gespeichert wird. (Alle anderen Angaben in Beispiel 11.1 sind selbst-erklärend.)

Beispiel 11.2

�������0������ ����������1��� ������������� ��������������� ������������2����3�45�!����������6��������-7'��%�-70�����2580-�29 : ���������;������<�������6���-7=>����66�������������2��������������%����� ������������������������%����� ����������?������������%����� �������������������������������������������������������������������"���������@A$����!���������6"�B-70���������-����-����"-7'�$$������� ���������6"�"����%�-70������������-�7��"-7'�$$�%%�����$������� ����������C��������!�������������C����������������"*<�������������-7�8�/�*$ �����������������%������������������"$ �����������?�����������������������6�������<��D�����������2������D�����������6����������=�6���������������������������������������������9������������������������C!���������������������E�����"*2955�"259������������������28'�������������������������$���������"����������������F9 F#�F�9?3-9G:.HF#�F-,//�-7//�-737���//2��������//

CLOUDSCAPE

Page 381: Java in Datenbanksystemen

����� ��� ������������ ���� ������� ���

����������������������F$*$ ������������&����":E���������$!���������������������E�����"*2955�"259�����������������28'�������������������������$�����"���������������F9 F#�F�9?3-9G:.HF#�F-,//�-7//�-737���//2��������//������������������������F$*$ ������������&�����������C!������������������E�����"*2955������������� ������C.�6�����-���� ������C"�������������F�����������������������F#F9 ��9?3-9G:.HF$*$ ���������&����":E���������$!&�������������������������G�������;�������������������C!����������������������E�����"*-?8 �G975:� �������*$ ������������&����":E���������$!&������������������E�����"*2?:9G:�G975:� �������"�3���.(G:):?�(8G�������������(055� ?.'9?I��:I#����������:?.95.>:" ������$�$*$ �������������C����������������"* �������=G��������������*$ ������������ ������@A���%�!��D������������� ������"*����������6�����*#J�KL#M$#��D������������� ������"*���������*#K�NM#HO$#��D� ������"*9N=���������������������������*#HKK�KM#H$& ����������������-��������������������� ������������������6���������������� ���������������������%�������������������"*.(�:?G�������������.(G8� ��������<950:��"P#�P$*$ ������������6��"������%O ��Q�������� ��++$������������!�������������������������.��"H#���$ �������������������������8�����"R#��@�A�$ �����������������������E�����0����"$ �����������������C����������������"���������0����2����"$+*�?��������������������������6���*$ ������������&���������������9���� �����������������������������C����������������"*/�<��������� �������,�*$ �������������C����������������"*9�6��6����� ������=��������"$=�������������'������,�*$ ���������������%�������E�����4���C"*�:5:2G����������?8'� �������*$ ������������D����"�����E�"$$�����������������C����������������"������8�����"H$$ ���������������<��D�����������������������������������������������C����������������"*/�<��������� �������,�*$ �������������C����������������"*9�����������������HJ�>������������������������������"$*$ ���������������%�������E�����4���C"*�:5:2G��07�G?.()"�����������������������������"$��?8'�O��8?�HJ$��?8'� �������*$ ������������D����"�����E�"$$�����������������C����������������"������8�����"H$$ ���������������������������������9�6������D������������������C����������������"*/�9�6��6���� ������='��������������

Page 382: Java in Datenbanksystemen

��� ����������� ��

�������������9�6���,�*$ ���������������%�������E�����4���C"*�:5:2G������������(��"$#������������������������ ����"$#������������)���� ����"$��������������?8'� �������*$ ������������D����"�����E�"$$�����������������C����������������"*���(��"$,�*�+�������8�����"H$�+�����������������*�/���� ����"$,�*�+�������8�����"R$�+�����������������*�/����)���� ����"$,�*�+�������8�����"J$$ ���������������-��������������������D������������������C����������������"*/�9�6��6���� ������='������������������������,�*$ ���������������%�������E�����4���C"*�:5:2G����������?8'� �������*$ ������������D����"�����E�"$$!���������������� ����������%�" ������$������8�����"H$ �����������������C����������������"*���(��"$,�*�+�������(��"$�+�*����������������/���� ����"$,�*�+������� ����"$�+����������������*�/����)���� ����"$,�*�+�������)���� ����"$$ ������������&��������������9����������������������������������������������������������������"$ ���������������������"$ ��������&����������9��6����������-72=���������������,=============���������������45='��������D��6��������������45:E�������������������"�45:E���������$��������!������������-70��������D�45:E�������"�$ ��������&������������":E���������$!�������������C����������������"*/�===�0�����������������===/�*$ �����������������������G���"$ ��������&����&��:�������'��&

Die Ausgabe des Beispiels 11.2 sieht folgendermaßen aus:

<�������������-7�8� �������=G��������������H�?����������6���H�?����������6���H�?����������6���<��������� �������,9�6��6����� ������=��������"$='������, �����������������6������ ����,�J�KL�'����,�M ����������������� ����,�K�NM�'����,�HO �������9N=��������������� ����,�HKK�KM�'����,�H<��������� �������,9�����������������HJ�>������������������"$ ������������ ������������

Page 383: Java in Datenbanksystemen

����� �������������� ���

�������9N=��9�6��6���� ������='���������������9�6���,���(��"$,�����������6���������� ����"$,�J�KL����)���� ����"$,�HK�K���(��"$,����������������� ����"$,�K�NM�������)���� ����"$,�KN�M���(��"$,�9N=��������������������� ����"$,�HKK�KM�������)���� ����"$,�HKK�KM9�6��6���� ������='������������,���(��"$,�����������6��������� ����"$,�J�KL�����)���� ����"$,�HK�K���(��"$,����������������� ����"$,�K�NM�������)���� ����"$,�KN�M���(��"$,�9N=��������������������� ����"$,�HKK�KM�������)���� ����"$,�HKK�KM

Im ersten Teil des Beispiels 11.2 wird mit Hilfe der execute()-Methode das Registrierender in Beispiel 11.1 erstellten Klasse Produkt vorgenommen. Dies ist notwendig, fallsbei der graphischen Darstellung der Tabelle Produkte, die Java-Klasse Produkt alsDatentyp der Spalte produkt erscheinen soll. (Die graphische Darstellung der Tabelleneiner Datenbank werden bei Cloudscape mit Hilfe der Komponente Cloudviewermöglicht.) Die Cloudscape-Methode replaceJar() ersetzt die eventuell vorhandenegleichnamige Klasse im Java-Archiv, während addJar() die Klasse hinzufügt.

Bei der Erstellung einer Tabelle muss die Spalte, die die Java-Klasse als Datentyperhält, mit der SERIALIZE-Angabe definiert werden. Damit wird dem System mitge-teilt, dass es sich um einen benutzerdefinierten Datentyp handelt, der als Java-Klasseexistiert.

Im weiteren Teil des Programms werden mit Hilfe der INSERT-Anweisung drei Reihenin die Tabelle Produkte eingefügt, die dann mit den verschiedenen Formen der SELECT-Anweisung ausgegeben werden.

���% ����������&������� ��

Das Cloudscape-System besteht aus mehreren Komponenten, die einzeln oder imZusammenspiel eingesetzt werden können. Das Basisprodukt ist Cloudscape, das einobjektorientiertes Datenbanksystem darstellt. Das ganze System existiert in Form eineseinzigen Java-Archivs namens cloudscape.jar.

Neben dem Basisprodukt enthält das Softwarepaket noch folgende Komponenten:

� Cloudview

� Cloudconnector

� Cloudsync

� ODBC-JDBC-Bridge.

Abbildung 11.1 zeigt alle Produkte von Cloudscape in Übersicht.

In den folgenden Abschnitten werden die drei erst genannten Produkte beschrieben.(Ein ODBC-JDBC-Bridge ist ein JDBC-Treiber, der in Kapitel 4 schon beschriebenwurde.)

Page 384: Java in Datenbanksystemen

�� ����������� ��

���%�� ��������

Cloudview ist ein Entwicklungswerkzeug, das für den Entwickler bzw. Benutzer dieHauptschaltzentrale darstellt und eine grafische Oberfläche enthält, die ähnlich derKomponente namens Steuerzentrale bei IBM DB2 ist (siehe Abbildung 11.2). DieseKomponente wird verwendet, um Cloudscape-Datenbanken zu erzeugen und zuadministrieren. Mit Hilfe von Cloudview kann man u.a. folgende Aufgaben ausfüh-ren:

� eine Datenbank erstellen

� eine Tabelle erstellen und Tabellendaten lesen

� Tabellendaten laden

� SQL-Anweisungen ausführen

� Objekte lesen und Methoden ausführen

� die Verbindung zu einer Datenbank herstellen.

!�����"���#�$������ ���%�����

�������

Das Lesen einzelner Objekte und die Ausführung von Methoden wird mit einemzusätzlichen Werkzeug namens ObjectInspector durchgeführt, das ein Teil vonCloudview ist.

Page 385: Java in Datenbanksystemen

����� �������������� ��&

���%� ���������

Bei Cloudsync handelt es sich um ein übergeordnetes Produkt, das mit der Basisver-sion von Cloudscape nicht geliefert wird. Vielmehr umfasst Cloudsync das kompletteCloudscape-System und zusätzlich die Synchronisations-Technologie namens LUCID,die zur Synchronisation der Daten von verteilten Anwendungen benötigt wird, umDatenkonsistenz zu gewährleisten. Mit anderen Worten, falls man auf die Synchronisa-tions-Technologie angewiesen ist, kauft man Cloudsync anstatt Cloudscape.

Cloudsync ist entstanden, weil der ursprüngliche Grundgedanke war, das Cloud-scape-System für mobile Rechner einsetzen zu können. Mit LUCID wird die Synchro-nisations-Technologie, die bei den mobilen Rechnern unerlässlich ist, angeboten.

Cloudsync erlaubt es, Teile einer gemeinsamen Quelldatenbank (shared source database)als Kopien auszugliedern. Diese Kopien werden als Zieldatenbanken (target databases)in einem verteilten System bezeichnet. Anwendungen haben volle Lese- und Schreib-zugriffe auf die Daten einer Zieldatenbank, ohne dabei auf die Daten der Quelldaten-bank zugreifen zu dürfen.

!�����"���#�$�����'���(�)�*��+������+��,

�������

Die Konfiguration von Cloudsync eignet sich hervorragend für den mobilen Ein-satz, da somit z.B. Verkäufer, die unterwegs sind, eine Zieldatenbank verwenden

Page 386: Java in Datenbanksystemen

��- ����������� ��

Bei der Synchronisierung werden von Cloudsync Verzeichnisobjekte, Daten und Java-Objekte von einer Quelldatenbank zu einer oder mehreren Zieldatenbanken kopiert.Die verwendete Technologie ermöglicht es, die Teilnehmer von der ständigen Netz-werkverbindung zu trennen und dennoch Datenkonsistenz zu gewährleisten. Dienachrichtenbasierte Synchronisation muss lediglich zum Auffrischen der zentralenDaten kurz einen HTTP-Kanal zum Server öffnen.

Damit wird auch eine verbesserte Performance erreicht, d.h. die Antwortzeiten steigenstark an, da die Daten lokal gespeichert sein können. Der Caching-Mechanismusermöglicht die volle Leistungsfähigkeit der Hardware auszuschöpfen, ohne auf Netz-werkverbindungen warten zu müssen oder mit anderen Benutzern in Konflikt zukommen. Die nicht immer notwendige Verbindung zum Server verhindert effektivSicherheitsrisiken, beispielsweise bei der Netzübertragung über das Internet. Da jederBenutzer nur den Teil der Daten erhält, die er für seine Applikation benötigt, wirdauch sichergestellt, dass kritische Daten von falschen Benutzern nicht gelesen werdenkönnen.

���%�% ����������� �"

Cloudconnector ist eine Komponente in der Server-Umgebung, die HTTP- und JDBC-Verbindungen zu Cloudscape anbietet. (Für die Erläuterung des Begriffs Server-Umge-bung siehe den Abschnitt »Cloudscape im Client/Server-Modus«.) Cloudconnectorunterstützt den Mehrbenutzerbetrieb und Connection Pooling und kann als vollständi-ger Web-Server verwendet werden, der dann Cloudscape in einem Servlet ausführt.

Cloudconnector besteht im Wesentlichen aus zwei Teilen: dem JDBC-Server für denMehrbenutzerbetrieb und einer dazu kompatiblen Client-Software. Diese zweite Soft-warekomponente wird von der Firma WebLogic auch unter dem ProduktnamenWebLogic angeboten und wurde speziell für die Benutzung mit Cloudview angepasst.

Cloudconnector erlaubt den Zugriff auf beliebig große Datenbanksysteme (wie z.B. Ora-cle) unter Erhaltung der Sicherheits- und Transaktionsintegrität. Durch die Java-Reali-sierung stehen vielfache Einsatzmöglichkeiten wie Servlets, Applets oder Java-Client-Server-Anwendungen zur Verfügung. Die Administrierung von Cloudconnector erfolgtüber eine TCP/IP-Verbindung durch Servlets mit Hilfe des HTTP-Protokolls. Eine Java-basierte Management-Konsole erlaubt sowohl die sichere Konfiguration des Servers alsauch der aktiven Clients.

können. In diesem Fall enthält die Zieldatenbank eines Verkäufers genau den Teil der ganzen Datenbank, der für ihn relevant ist. Wichtig ist, dass ein Verkäufer nicht nur lesend, sondern auch schreibend auf seine Zieldatenbank zugreifen kann.

Page 387: Java in Datenbanksystemen

����� ���.����� ���

Da Cloudconnector in Java realisiert wurde, stehen auch dessen Fähigkeiten wie JNDIzur Integration des Systems mit anderen Namensdiensten wie LDAP, NDS, ActiveDirectory oder auch RMI und IIOP-Unterstützung für Corba zur Verfügung.

Um sowohl Sicherheit als auch Performance zu garantieren, werden weiterhin Trans-aktionen, Firewalls und Cache-Mechanismen verwendet. Mechanismen zum Einlog-gen erlauben das Aufzeichnen und Überwachen sämtlicher Aktivitäten. Connection-Pooling erlaubt den Zugriff vieler Clients ohne nennenswerte Performance-Verluste,und ein ausgereiftes Verbindungsmanagement ermöglicht einen hohen Grad an Ska-lierbarkeit.

���������������� ����������� ��������������������

Für die Verwendung von Cloudconnector in Client-Programmen sind folgende Anga-ben wichtig:

Im Klassenpfad von Java müssen folgende Einträge vorhanden sein:

Q2�S����������������Q2�S�6���D��������������������������Q2�S�6���D����������������������D��������E�����Q2�S�6���D���������������������������Q2�S��������������

Als Treiber wird COM.cloudscape.core.WebLogicDriver verwendet, die URL sieht syn-taktisch folgendermaßen aus:

����,���������,D�������@=�����A,@����������� �����A@�������� ��������A�������������������� �������������@T��������������������A

Fast alle wichtigen Einstellungen wie Multithreading, Caching, Kennwörter, Protokoll-einstellungen oder ähnliches werden in der entsprechenden Properties-Datei namensweblogic.properties angegeben. Weitere Informationen dazu finden sich in der zuCloudscape gehörigen Dokumentation.

���' ����������(������

Die von Cloudscape verwendete Programmierschnittstelle heißt JDBC. Jede Cloud-scape-Anwendung verwendet daher JDBC API, um auf den Datenbank-Server vonCloudscape (und damit auch auf die darunterliegenden Daten) zuzugreifen. Abbil-dung 11.3 zeigt dies.

Auf der Basis von JDBC kann man Cloudscape in zwei unterschiedlichen Modi betrei-ben:

� eingebettet in eine Anwendung

� im Client/Server-Modus.

Page 388: Java in Datenbanksystemen

��� ����������� ��

Folgende Unterabschnitte beschreiben die beiden Modi.

���'�� ��������� �������������������������)��������

Der Datenbank-Server von Cloudscape kann in jedem Softwarepaket, wo Java abläuft,eingebettet werden (embeddable engine). Das bedeutet, dass der Datenbank-Server selbstTeil einer Anwendung sein kann, so dass Datenbank und Anwendung am gleichenRechner laufen.

Obwohl eingebettet, erfolgt der Zugriff auf die Datenbank immer noch mit Hilfe vonJDBC. In diesem Fall macht der JDBC-Treiber aber nichts anderes als Daten zu und vonder Datenbank zu transferieren, ohne dabei eine Netzwerk-Verbindung zu benötigen(siehe Abbildung 11.4).

Der Benutzer sieht nur eine einzelne Java-Applikation, und der Datenbank-Server istdabei »unsichtbar«. Aus diesem Grund muss der Benutzer keine Konfigurationsein-stellungen vornehmen, womit die Administration des Systems entfällt.

!�����"���#�$�/����!%0� ���%��"� �������*�����������(1������� ��

�������

Anwendungen mit Diensten für mehrere Benutzer können, genauso wie Ein-Benut-zer-Anwendungen, mit dem eingebetteten Cloudscape laufen. Solche Anwendun-gen laufen in demselben JVM wie Cloudscape und tätigen (über JDBC) Aufrufe andie Datenbank.

Page 389: Java in Datenbanksystemen

����� ���.����� ���

���'� ������������������ *$�"�"�(����

Zusätzlich zur Einbettung des Systems in eine Anwendung kann Cloudscape auch ineiner Client/Server-Umgebung laufen. In diesem Fall befindet sich Cloudscape ineiner sogenannten Server-Umgebung (Server Framework), die im Grunde nichts anderesals einen Softwareteil darstellt, der die Netzwerkkommunikation bereitstellt und ver-waltet. Wird Cloudscape in einer Server-Umgebung gestartet, können beliebig vieleBenutzer gleichzeitig auf die Datenbank, die auf einem zentralen Server läuft, zugrei-fen.

Cloudscape untersützt zwei Server-Umgebungen:

� RmiJDBC-Lösung

� Cloudconnector

Die RmiJDBC-Lösung ist eine speziell für Cloudscape angepasste Version eines opensource-Produktes. RmiJdbc benutzt das RMI von JavaSoft, um eine Client-Anforderungzum Server zu transportieren, der sich wiederum mit einem JDBC-Treiber verbindet.Cloudscape läuft eingebettet innerhalb des RmiJDBC-Servers, und der Client startetAufrufe an den lokalen RmiJDBC-Client-Treiber (siehe Abbildung 11.5). Vom RmiJDBC-Server werden nur JDBC-Anfragen unterstützt.

Die zweite Lösung – mittels Cloudconnector – haben wir schon in einem vorherigenAbschnitt dargestellt. Für diese Lösung ist signifikant, dass sowohl über JDBC als auchüber HTTP zugegriffen werden kann (siehe Abbildung 11.6).

!�����"���# $�����2�������"�+�������� �����������!�,���"

Page 390: Java in Datenbanksystemen

��� ����������� ��

!�����"���#&$�����3��/����45��"

!�����"���#-$�������������

Page 391: Java in Datenbanksystemen

����� ���!��*�+��6�������*����7 ���

���+ ����������)"�����,#����� �����-

Das Cloudscape-System wird mit einer Sammlung von Bibliotheken geliefert, die wirin diesem Abschnitt erläutert werden. Folgende Bibliotheken sind der Bestandteil vonCloudscape:

� cloudscape.jar bzw. cloudsync.jar

� client.jar

� tools.jar

cloudscape.jar stellt die Basisbibliothek des Cloudscape-Systems dar. Diese Bibliothekbeinhaltet den Datenbank-Server. Falls Cloudscape in dem eingebetteten Modus läuft,muss diese Bibliothek verwendet werden. In der Client/Server-Umgebung muss sienur serverseitig benutzt werden. Die Bibliothek cloudsync.jar entspricht der cloud-scape.jar, falls Cloudsync eingesetzt wird. Dementsprechend wird cloudsync.jar ineinem synchronisierten System verwendet.

Die client.jar-Bibliothek wird für Client/Server-Umgebungen verwendet, die überJDBC laufen. Die tools.jar-Bibliothek wird benötigt, um front end-Werkzeuge (wieCloudview, Objectinspector usw.) benutzen zu können.

���. )����������/�������� ���������������

Cloudscape ist ein in der Sprache Java implementiertes Datenbanksystem. Diese Tatsa-che ermöglicht eine einfachere Programmierung, was wir mit einem Beispiel zeigenwerden. Dieses Beispiel stellt eine äquivalente Lösung für das Informix-Beispiel mitKollektionen dar (siehe Beispiel 8.4).

Das Cloudscape-Beispiel zeigt, wie sich mit Hilfe eines Java-Datenbanksystems derZugriff auf komplexe Datenbankobjekte wie Menge oder Liste stark vereinfachen lässt.Es ist hier jedoch zu beachten, dass die eigentlichen Datentypen selbst implementiertwerden müssen und dafür kein Werkzeug (wie ClassGenerator bei Informix z.B.) zurVerfügung steht, das die Datentypen automatisch in Java-Klassen konvertiert.

Bei Verwendung eines Java-Datenbanksystems muss man folgendermaßen für die Ver-wendung einer Spalte mit dem Java-Datentyp vorgehen:

1. den Datentyp in Java implementieren

2. die Tabelle mit diesem Datentyp definieren

3. die jeweiligen Objekte von diesem Typ in der Datenbank speichern.

Page 392: Java in Datenbanksystemen

��� ����������� ��

Das Programm, das wir erläutern werden, zeigt, dass mit einem in Java realisiertenDatenbanksystem die Programmierung wesentlich einfacher sein kann. Das gilt beson-ders für die Implementierung von objektorientierten Konzepten.

Weil das Cloudscape-Programm mit Beispiel 8.4 äquivalent ist, benötigt es zwei wei-tere Java-Klassen, welche die in Informix verwendeten Typen ROW und LIST in Javaabbilden.

Beispiel 11.3 zeigt die Implementierung der Java-Klasse autor, die etwa der Informix-SQL-Anweisung

2?:9G:�?8U�GI :�����3�"����2V9?"RO$#��������:G"2V9?"RO$�(8G�(055$$

entspricht.

Beispiel 11.3

������������� ��������������� ���2�������������6���������9�������������W���������(����������������������<��������������������������������������������!��������������������� �����������V�������������%���D�V�����"$ ���������������"�����������#�������@A�������$����!�����������������%���� ��������6��"������%�O ���Q�������������� ��++$��������������������������"�������@�A�$ ����&�������9����������.�������������������������������"$����!����������������������%�*(��,�*+���+*/�/�<������,�* ��������8�����@A���%����������9��C"$ ��������6��"������%O ��Q�������� ��++$�������������������+%��@�A�+�*#�* ��������������������� ����&&

�������

Bei Datenbanksystemen wie Informix Dynamic Server oder Oracle wird zuerst dieTabelle mit den jeweiligen objektorientierten Datentypen, die das jeweilige Systemunterstützt, erstellt. Danach werden daraus automatisch oder auch manuell Java-Datentypen generiert, und schließlich können die Daten über Java eingefügt odergelesen bzw. verändert werden.

Page 393: Java in Datenbanksystemen

!�,���"��5"���*�������+�������� �� ���

Der Unterschied zwischen der Java-Klasse autor und der entsprechenden Informix-SQL-Anweisung CREATE ROW TYPE besteht vor allem darin, dass der bei Informixverwendete Reihentyp ein zusammengesetzter Typ ist, der in der Datenbank selbstabgespeichert und verwaltet wird, während bei Cloudscape ganze Java-Klassen in dieDatenbank geschrieben werden können, die dann als Datentyp einer Spalte verwendetwerden können.

Informix-Beispiel 8.4 enthält den Reihentyp autor_t, der selbst zwei Spalten beinhaltet:die Spalte name, die als Standarddatentyp definiert ist, und die Spalte vornamen, dieals Menge definiert ist. Die oben gezeigte Java-Klasse enthält ebenso eine Variablename, welche den Namen des Autors enthalten wird sowie eine Menge von Vor-namen, die in Java in diesem Fall auf eine Instanz der Klasse HashSet (enthalten imjava.util-Paket) abgebildet werden.

Das Lesen und Schreiben dieser beiden Werte muss nicht extra implementiert werden,weil die entsprechenden Methoden von Cloudscape implizit für jede Klasse, die inihrer Definition die Angabe implements Serializable enthält, erstellt werden.

Für das Beispiel wurden nun lediglich noch zwei Hilfsmethoden implementiert, zumeinen ein Konstruktor, mit dem sich ein neuer Datentyp mit Inhalt anlegen lässt, undzum anderen die toString()-Methode zur einfachen Ausgabe des Inhalts. Die Methodeund der Konstruktor sind nicht unbedingt notwendig, erleichtern aber die spätereBenutzung des Datentyps.

Der Zugriff auf die Elemente name und vornamen kann durch die public-Implemen-tierung direkt über den Zeiger auf den Datentypen und auch die in der HashSet-Klasse verfügbaren Methoden erfolgen.

Die im Beispiel verwendete Tabelle enthält neben den allgemeinen Buchinformationennicht nur einen Autoren, sondern gleich mehrere, die über die Informix-SQL-Anwei-sung

2?:9G:�?8U�GI :�����3��"�����2V9?"HJ$�(8G�(055#�������3������5.�G�"����3��(8G

(055$#�����3������2V9?"MO$ $

in Beispiel 8.4 als Liste definiert wurden. Die Repräsentation einer derartigen Liste vonAutoren wird durch die Klasse Autoren_liste, die in Beispiel 11.4 dargestellt ist, reali-siert.

Beispiel 11.4

������������� ��������������� ���2�������������6�����������9������������������9������3���������������������������!���������9��C5������%���D�9��C5���"$

Page 394: Java in Datenbanksystemen

�� ����������� ��

���������9������3�����"����@A������$��!������6��"������%�O ���Q������������� ��++$��������������"�����@�A$ ��&�����������9�������������E�����������������9����"��������E$��!�������������"����$�����"����E$ ��&�����9�����������������,������������������������"$��!�������������������%** ������6��"�����%O ��Q������"$ ��++$�����������������+%������"�$�+*/�* ������������������� ��&&

Die Klasse Autoren_liste in Beispiel 11.4 ist als Java-Datentyp wieder als Serializabledefiniert und enthält als Java-Äquivalent zur Liste bei Informix lediglich eine Variablevom Typ ArrayList. Zum einfachen Erstellen einer neuen Autorenliste wurde ein ent-sprechender Konstruktor implementiert, der die passenden Daten übernimmt und ein-trägt. Weiterhin wurde für einen einfacheren Zugriff auf die Listenelemente einegetAutor()-Methode implementiert. Die toString()-Methode gibt den Inhalt des Con-tainers aus und greift dazu auf die in der Autor-Klasse deklarierte toString()-Methodezu.

Nachdem wir die zwei Hilfsprogramme, die die notwendigen Java-Klassen implemen-tieren, gezeigt haben, sind wir in der Lage, das Cloudscape-Programm zu erörtern.Beispiel 11.5 zeigt dieses Programm.

Beispiel 11.5

�������0������ ����������1��� ������������� ��������������� ������������2����32���������!����������6��������-7'��%�-70�����2580-�29 : ���������;������<�������6���-7=>����66�������������2��������������%����� ������������������������%����� ����������?������������%����� �������������������������������������������

CLOUDSCAPE

Page 395: Java in Datenbanksystemen

!�,���"��5"���*�������+�������� �� ��&

������������������������"���������@A$����!��������6"�B-70���������-����-����"-7'�$$������� ��������6"�"����%�-70������������-�7��"-7'�$$�%%�����$�������

����������C��������!

�������������C����������������"*<�������������-7�8�/�*$ �����������������%������������������"$

���������������-����6���J�7����������������������������������@A������%�!*J=KJRMLL=JJ=K*#*H=MXMKR=ONM=Y*#*O=NYH=�������������MKKHY=N*& ������������������@A�������%�!*:�6�������������*#*)��������������������U�������-2:�9����������*#*?��=G����������������8�����=8��������'�������*& ������������9������3�����@A���%�!��D�9������3�����"������������������������D�����@A!���D�����"*'66���*#��D����������������������������@A!*�����*&$#�����������������������������������D�����"*G����������*#��D����������������������������������������@A!*�������6*&$#�����������������������������������D�����"*>������*#��D����������������������������������������@A!*2�������*&$�������������������������������&��������������������������$#����������������������������D�9������3�����"������������������������D�����@A!���D�����"*������C*#��D�����������������������������@A!*����*&$#�����������������������������������D�����"*V�*#��D����������������������������������������@A!*U��*&$#�����������������������������������D�����"*'���*#��D����������������������������������������@A!*-��*&$�������������������������������&��������������������������$#����������������������������D�9������3�����"������������������������D�����@A!���D�����"*�����*#��D�����������������������������@A!*7��*&$#�����������������������������������D�����"*)��������*#��D����������������������������������������@A!*)���*&$#�����������������������������������D�����"*�����*#��D����������������������������������������@A!* ��*#*G����*&$�������������������������������&��������������������������$��������������������������& ������������������������G�������;������������������C!��������������������E�����"*-?8 �G975:�����*$ �����������&����":E���������$!&

�����������������E�����"*2?:9G:�G975:�����"�����2V9?"HJ$�(8G

Page 396: Java in Datenbanksystemen

��- ����������� ��

�������������(055� ?.'9?I��:I#�9������3�������������������:?.95.>:"9������3�����$#�����3������2V9?"MO$�$*$ ������������C����������������"*�������������*$ ������������������-��������������������� �����������������������������������6��������������� ���������������������%����������������������������"*.(�:?G�.(G8������<950:��"P#�P#�P$*$ �����������6��"������%O ��Q����������� ��++$�����������!������������������������������"H#�����@�A�$ ������������������������8�����"R#��@�A���$ ������������������������������"J#������@�A$ ����������������������E�����0����"$ ����������������C����������������"���������0����2����"$+*�?�������������������������6���*$ �����������&

��������������:��������������7�����������������������%�������E�����4���C"*�:5:2G�����#�9������3�����#����������������3�������?8'�����������������UV:?:�����������FO=ZF*$ ������������C����������������"*9�6��������6����/�*$ �����������9������3����������3���� ����������������������3��%** �����������?�����������R �����������D����"�����E�"$$!����������������������������������,������������������3���%�������8�����"*����*$���������"$ �����������������:���8���������GC������3�����������������������������3�����%����������������"9������3�����$������8�����"*9������3�����*$ ������������������.������������3������������#�����������������������������������������='����������������������C����������������"����3����$ ���������������[������������U������"����H��9�����D������W�����$�������������������3��������9����"O$�����%�*�������* ������������������-���9����������������R��<���������������,�������������������3��������9����"O$����������"*����*$ ������������������[������������9��C�������������-7������������������������������ ����������������������������������%�������������������"*0 -9G:�������:G���������������9������3������%�P�UV:?:�����������F*+����3��+*F*$ �����������������������8�����"H#����3����$ ���������������C����������������"�������E�����0����"$+*���������������?����"�$�����������*$ ������������&�����������������������9������������W��������U����#������D���������������������R�%�������E�����4���C"*�:5:2G�����#�9������3�����#�����������������3�������?8'������UV:?:�����������F*+����3��+*F*$ ��������������R���E�"$ �������������C����������������""9������3�����$���������������R����8�����"*9������3�����*$$

Page 397: Java in Datenbanksystemen

!�,���"��5"���*�������+�������� �� ���

��������������9����������������������������������������������������������������"$ ���������������������"$ ��������&����������9��6����������-72=���������������,=============���������������45='��������D��6��������������45:E�������������������"�45:E���������$��������!������������-70��������D�45:E�������"�$ ��������&������������":E���������$!�������������C����������������"*/�===�0�����������������===/�*$ �����������������������G���"$ ��������&����&��:�������'��&

Die Ausgabe des Beispiels 11.5 sieht folgendermaßen aus:

<�������������-7�8��������������H�?����������6���H�?����������6���H�?����������6���9�6��������6����(��,������������<������,�7��#(��,�)��������������<������,�)���#(��,������������<������,� ��#�G����#H�?����"�$�����������(��,��������������<������,�7��#�����#(��,�)��������������<������,�)���#(��,������������<������,�G����#� ��#

Nach der Erstellung der Verbindung zur Datenbank, die im Embedded-Framework-Modus erst zu diesem Zeitpunkt hochgefahren wird, werden in Beispiel 11.5 zuerst allebenötigten Daten, die später in die Tabelle eingefügt werden sollen, deklariert. DieDaten werden dabei implizit bei der Deklaration als Vektoren (Arrays) definiert. DasBesondere dabei ist die implizite Definition der Vektorinhalte in der Deklaration, dieüber <Typ>[]{...}�erfolgt, z.B.:

��D�����@A!���D�����"*'66���*#��D�������@A!*�����*&$#����&�

Nachdem die Daten definiert wurden, wird die eventuell bereits vorhandene Tabellemit Hilfe der DROP TABLE-Anweisung entfernt. Anschliessend wird die Tabelle mitdem Java-Spaltentyp durch:

2?:9G:�G975:�����"�����2V9?"HJ$�(8G�(055� ?.'9?I��:I#�������3�������:?.95.>:"������3�����$#�����3������2V9?"MO$�$

erstellt. Wie wir schon in Beispiel 11.2 erörtert haben, wird das SERIALIZE-Schlüssel-wort für den Datentypen, der die Java-Klasse darstellt, verwendet.

Page 398: Java in Datenbanksystemen

��� ����������� ��

Mit Hilfe einer Instanz der PreparedStatement-Klasse werden alle vorher definiertenDaten in die Tabelle eingetragen. Eine einfache SELECT-Anweisung liest danach einenBuchtitel in eine Ergebnismenge (ResultSet) ein, welche über eine while-Schleife alleDaten der Ergebnismenge ausgibt und verarbeitet.

Das besondere bei Cloudscape ist, dass eine Anweisung wie:

����3�����%�"9������3�����$������8�����"*9������3�����*$

völlig ausreicht, um den Java-Datentypen aus der Datenbank zu lesen und in Java zurVerfügung zu stellen. Es sind hier keinerlei Typabbildungen und Konvertierungen wiebei Oracle oder Informix notwendig, wodurch alles sehr einfach und übersichtlichbleibt.

Für die Ausgabe des Inhalts des komplexen Typen genügt nun die Angabe von:

�C����������������"����3����$

da die toString()-Methode bereits vorher implementiert wurde und so automatischaufgerufen wird. Änderungen am Inhalt können direkt erfolgen, indem man auf dieKlassenvariablen zugreift, wie z.B.:

����3��������9����"O$�����%�*�������*

um den Namen des Autors zu ändern, bzw. über die Methoden der HashSet-Klassedie Vornamen zu modifizieren:

����3��������9����"O$����������"*����*$

Damit ist es offensichtlich, dass man in diesem Fall die meisten ansonsten etwasumständlich zu implementierenden Funktionen auf Vektoren (Arrays) oder Strukturen(Structs) sehr einfach programmieren kann. Um die Änderung in der Datenbank wirk-sam zu machen, wird lediglich über eine Instanz der PreparedStatement-Klasse dasgeänderte Objekt zurückgeschrieben. Die Überprüfung der Datenbank erfolgt außer-halb der Schleife in einer erneuten Abfrage.

���0 1������2�����

Cloudscape ist ein Datenbanksystem, das komplett in Java geschrieben ist. Die wich-tigsten Eigenschaften von Cloudscape sind:

� keine Administrierung notwendig

� Unterstützung verteilter Umgebungen

� Unterstützung objektorientierter Konzepte

Page 399: Java in Datenbanksystemen

8� ����( ���" ���

� wenig Speicherbedarf beim Laden (small footprint)

� läuft mit jeder (zertifizierten) JVM.

Zusätzlich dazu ermöglicht dieses System die Verwendung von Java-Klassen alsDatentypen einzelner Tabellenspalten. Dies ermöglicht sowohl einen fließenden Über-gang zwischen Geschäfts- und Datenlogik als auch eine einfache Programmierung.

Das nächste Kapitel beschreibt das zweite Java-Datenbanksystem namens PointBase.

Page 400: Java in Datenbanksystemen
Page 401: Java in Datenbanksystemen

�� �������

In diesem Kapitel wird das zweite Java-Datenbanksystem namens PointBase beschrie-ben. Der Aufbau des Kapitels entspricht weitestgehend dem des vorherigen Kapitels.Nach der Beschreibung der Entwicklungsgeschichte und der Eigenschaften dieses Pro-duktes werden sowohl verschiedene Editionen als auch die unterschiedlichen Kompo-nenten, die bei diesen Editionen existieren, beschrieben. Am Ende des Kapitels werdenAnwendungsmöglichkeiten von PointBase gezeigt.

���� �������������������������������

Die Firma PointBase wurde im Jahre 1998 von Bruce Scott gegründet. Scott war einerder Gründer der Firma Oracle und dort als Entwickler tätig. Er war maßgeblich an denArbeiten zu den Oracle Versionen 1, 2 und 3 beteiligt, wechselte dann aber zur GuptaCooperation und gründete schließlich die Firma PointBase.

Laut Firmenprofil liegt der Fokus und das Ziel von PointBase darin, Daten einer Firmaüberall zugänglich zu machen. Mit anderen Worten heißt das, den Markt für mobileRechner zu befriedigen. Dank der Tatsache, dass das Produkt sehr wenig Arbeitsspei-cher für das eigene Laden braucht, zielt die Firma PointBase auch stark auf den Tele-kommunikationssektor und smart devices ab, d.h. Datenbankinformation intelligentenMobiltelefonen bereitzustellen.

������ ���������������������

PointBase ist im Unterschied zu Cloudscape ein relationales Datenbanksystem.Obwohl grundlegende Eigenschaften von PointBase den Eigenschaften von Cloud-scape in vielen Bereichen sehr ähnlich sind, gibt es wegen der relationalen Architekturdieses Systems einige Unterschiede zu Cloudscape.

PointBase ist auf Grund der Java-Technologie komplett plattformunabhängig, d.h. aufjeder Maschine die eine JVM zur Verfügung stellt, kann das System ausgeführt wer-den. Die small footprint-Eigenschaft, die für alle in Java implementierten Datenbanksys-teme gemeinsam ist, trifft auch vollkommen auf das PointBase-System zu. Je nach

Page 402: Java in Datenbanksystemen

��� ����������� �

verwendeter Version benötigt das System einen Platzbedarf zwischen ca. 45KB (für einEinbenutzer-Micro-System) bis zu 1MB (für ein Mehrbenutzersystem).

Im Gegensatz zu Cloudscape erlaubt PointBase jedoch nicht das direkte Speichern unddie Verwendung beliebiger Java-Objekte in einer Tabelle. Es können beispielsweisekeine Klassen als Datentyp verwendet werden (siehe Beispiel 12.1). PointBase ist zwarin Java implementiert, stellt aber zusätzlich zu den herkömmlichen relationalen Daten-typen nur die SQL 99-Datentypen BLOB und CLOB zur Verfügung. (Für die Beschrei-bung von den Datentypen BLOB und CLOB siehe Kapitel 4.)

Genau diese beiden Datentypen ermöglichen die persistente Speicherung von Java-Objekten, jedoch mit Einschränkungen. Auf Grund der Tatsache, dass Java-Objekte zurLaufzeit binäres Format haben, können in einer Spalte vom Datentyp BLOB seriali-sierte Java-Objekte abgespeichert werden. Diese Art von Speicherung bietet aber nichtdie Möglichkeit, die Objekte direkt abzufragen bzw. zugehörige Klassenmethoden mit-tels SQL auszuführen. Natürlich besteht die Möglichkeit die Objektdaten wieder aus-zulesen, abzuändern und auszugeben. Nach dem Auslesen aus einer Tabelle hat manauch wieder vollen Zugriff auf die Klassenmethoden. Diese einfache Art von Objekt-speicherung mag für viele Fälle durchaus sinnvoll sein, dennoch ist man aber in derHandhabung relativ eingeschränkt. (Beispiel 12.1 verwendet die oben beschriebeneMethodik.)

Auf Grund der oben beschriebenen Einschränkungen bei der Verwendung des Daten-typs BLOB bietet PointBase eine weitere Möglichkeit zur Speicherung von Objektenan, die so genannte objektrelationale Abbildung (object relational mapping – ORM).Diese Technik bildet beliebige Objekte auf passende Datentypen einer Tabelle ab, ohnedabei den Objektinhalt auf irgendeine Art zu beeinflussen. Danach stehen einemBenutzer alle datenbankbezogenen Operationen zur Verfügung. Die Persistenz derDaten ist dabei gewährleistet, da diese Technologie die Wiederherstellung des eigent-lichen Objektes anhand der Tabellendaten ermöglicht. Optional kann man auch dieDaten zusätzlich in einem BLOB speichern, was aber den Nachteil hat, dass die Datenstets doppelt gespeichert werden müssen.

Der Mechanismus der objektrelationalen Abbildung ist in der Regel sehr komplex inder Anwendung, daher gibt es Werkzeuge von Drittanbietern, die diesen Vorgangweitgehendst automatisiert durchführen. Zwei Anbieter solcher Werkzeuge sind:

� Webgain Toplink ��������������� ������������������� �

� Sun Forte for Java ������������� ������������ �������������������

Page 403: Java in Datenbanksystemen

����� �������� ���

���� �������� ��������

PointBase wird in drei verschiedenen Editionen angeboten:

� Micro

� Embedded

� Server,

um eine möglichst breite Palette von Benutzeranforderungen zu unterstützen. Dieoben genannten Editionen unterscheiden sich erheblich in Umfang und Funktionalität.Folgende Unterabschnitte beschreiben alle PointBase-Editionen.

������ �������������

Die PointBase Micro-Edition wurde, basierend auf der J2ME (Java 2 Micro Edition)und J2SE (Java 2 Standard Edition) speziell für mobile Rechner entwickelt.

Entsprechend der Anforderung bezüglich smart devices besitzt PointBase Micro-Archiveinen Ladespeicherbedarf von ca. 45KB und eignet sich deswegen hervorragend fürsolche Geräte wie Handys und PDAs (Personal Digital Assistents). Applikationen fürdiese Geräte haben als oberstes Ziel, so wenig Speicher und so wenig Ressourcen wieirgendwie möglich zu belegen. Mit PointBase Micro verfügen diese über ein vollwerti-ges relationales Datenbanksystem, das kaum Administrationsaufwand mit sich bringtund sehr wenig Speicherplatz benötigt.

Micro wird in der Regel für eingebettete Betriebssysteme (Embedded OS) wie z.B. Win-dows CE oder Palm OS eingesetzt, lässt sich aber natürlich auch auf herkömmlichenPCs verwenden, was aber nur zu Testzwecken einen Sinn macht.

Technisch gesehen arbeitet die Micro-Edition mit einem Teilbereich von JDBC und Tei-len des SQL92-Sprachbestands. Das ist auch naheliegend, weil diese Edition sehr spar-sam mit dem Speicherplatz umgehen muss. Weiterhin werden Transaktionen undArchivierungsmechanismen als wichtige Datenbankkonzepte unterstützt.

Abbildung 12.1 zeigt die Architektur einer Anwendung, die PointBase Micro verwen-det.

�������

Die Java 2 Micro Edition ist eine von Sun eingeführte Java-Umgebung, die speziellfür smart devices wie z.B. Handys entwickelt wurde. Weitere Informationen überJ2ME können unter folgender Adresse gefunden werden: http://java.sun.com/j2me.

Page 404: Java in Datenbanksystemen

��� ����������� �

������ �������� �������

Die PointBase Embedded-Edition wurde speziell entwickelt, damit der Datenbank-Ser-ver von PointBase innerhalb einer Java-Applikation oder einer Internet-Anwendungeingebettet laufen kann. Die PointBase Embedded-Edition ermöglicht mehrere Daten-bankverbindungen gleichzeitig innerhalb derselben Java Virtual Machine aufzubauen.Das Ziel dieser Technologie ist es, dem Benutzer die Möglichkeit zu geben, mehrereInformationsdienste integriert in einem System bearbeiten zu können, die später beimBedarf mit den großen Datenbanksystemen wie Oracle und DB2 synchronisiert werdenkönnen. (Für die Synchronisation wird die später beschriebene Komponente namensUniSync verwendet.) Zielanwendungen dieser Art sind z.B. Netzwerkmanagement-Applikationen, CRM-Anwendungen (Customer Relationship Management) oder PersonalProductivity-Anwendungen, die mehrere Informationsdienste integriert in einer Appli-kation bearbeiten müssen und z.B. auf einem Laptop laufen.

Anwendungen dieser Art benötigen eine eingebettete Datenbank, die mehrere Daten-bankverbindungen zulässt. Der benötigte Speicherbedarf fürs Laden des Embedded-Servers beträgt ca. 800 KB. Dieser Server unterstützt die ganze Funktionalität einesrelationalen Datenbanksystems. Die Embedded-Edition bedarf nahezu keinerleiAdministrationsaufwands.

������ ������ ������

Die Server-Edition von PointBase stellt eine Datenbank für klassische Client-Server-Anwendungen zur Verfügung, um jederzeit über ein Netzwerk auf die Daten zugrei-fen zu können. Die Server-Technologie ermöglicht die Bearbeitung von globalen Datenmit Hilfe der Internettechnologien (wie z.B. HTTP oder einem Browser). Aus diesemGrund wird der PointBase-Server primär im e-Commerce-Bereich und anderen inter-netbasierten Anwendungsgebieten eingesetzt. PointBase Server stellt alle für Multi-benutzerbetrieb notwendigen Sicherheitsmechanismen zur Verfügung, wie z.B. daskomplette Transaktionskonzept mit verschiedenen Isolierungsstufen, reihenbasierteSperrmechanismen und Verschlüsselung.

������������������ ��������������� ��������������

Page 405: Java in Datenbanksystemen

����� �������� ���

Abbildung 12.2 zeigt eine Client-Server-Anwendung.

Tabelle 12.1 zeigt zusammenfassend die verschiedene Editionen von PointBase undihre Einsatzgebiete.

������������������ ���������� ����!�"��#��������$����%������� �

����������

��� �� ���

������������ � ����������������� ����������� ��

�!�������"�#���

��� ��������

������������

�������#�����$��%�

&���������

�������

�$��%�&�����������

�������

�$��%�&�����������

"�#�������$��

"''���������

�������#�����$��"''���

�������������������

������$&�

�������#�����$���"''����

�����������������������$&�

�������

�$��"''���������

(��#�����)����** )����**��������������

������"''�������

)����**��������������������

"''�������

+������)����**������

(��#����#����**

������������ ���#��������� ��������,�� ��� ��������,�� ���

)������''� �����*-���������������

�*����.�/����

������0

��������������"''�������

���.���������������������

����������������!������

�������%������

������"''���������

12��� �����.�

��3�����#4

&�������������'�� �(�������������#������� ������(����� �)�������

�������

Wie aus Tabelle 12.1 ersichtlich, benutzen alle PointBase-Editionen JDBC alsSchnittstelle für den Datenbankzugriff.

Page 406: Java in Datenbanksystemen

��* ����������� �

���� ��������3��'�������

PointBase enthält einige Komponenten, welche die Arbeit eines Entwicklers erleich-tern sollen. Zu diesen gehören:

� UniSync

� PointBase Server

� PointBase Console

� PointBase Commander.

Folgende Unterabschnitte beschreiben diese vier Komponenten.

������ ,�� ���

Die UniSync-Komponente (Universal Synchronization) wird benutzt, um die Synchroni-sation von PointBase zu den großen Datenbanksystemen (wie z.B. Oracle) zu unterstüt-zen. Diese Synchronisationstechnologie wird bei den mobilen Rechnern verwendet, d.h.wenn ein Außendienstmitarbeiter mobil mit Teilen einer Datenbank, die später miteinem anderen großen Datenbanksystem synchronisiert wird, arbeiten will.

Genauso kann aber PointBase UniSync für die Synchronisation von Daten zwischenmehreren PointBase-Datenbanken verwendet werden.

������ �������� �����

Der PointBase-Server dient zur Verwaltung der Server-Seite einer PointBase-Daten-bank. Dementsprechend wird diese Administrationskomponente ausschließlich mitder PointBase Server-Edition ausgeliefert.

Die Funktionalität dieser Komponente ist eingeschränkt: Das Werkzeug erlaubt nurdas Starten und Schließen einer Datenbank, sowie die Beobachtung der angemeldetenBenutzer und deren Aktivitäten (siehe Abbildung 12.3). Diese Funktionalität ist aufden ersten Blick nicht sehr umfangreich, bietet allerdings die wichtigste Funktionenund die Bedienung ist sehr schnell zu erlernen.

�������

Im Unterschied zu der ersten Komponente (UniSync), die bei allen PointBase-Edi-tionen zur Verfügung steht, können die übrigen drei Komponenten nur mit derEmbedded- und Server-Edition verwendet werden.

Page 407: Java in Datenbanksystemen

����� ��+�%���� ��,

������ ��������%�����

Die Console-Komponente (Abbildung 12.4) ist ein grafisches Datenbankadministra-tionswerkzeug (ähnlich wie Cloudview), das hauptsächlich zur Administration einerDatenbank (auf der Client-Seite oder im Embedded-Modus) verwendet wird. DieseKomponente erlaubt die Durchführung wichtiger datenbankspezifischer Operationenwie z.B.:

� Erzeugen einer Datenbank

� Datenbankverbindung aufbauen

� Anlegen von Tabellen

� direkte Ausführung der SQL-Anweisungen

�������������������� ��"��#���-���.�/�(�

�������������������� �� � ���

Page 408: Java in Datenbanksystemen

��0 ����������� �

� Benutzerverwaltung

� Indexerstellung, Transaktionen und andere Datenbankoperationen

�����5 ��������%�������

Die Commander-Komponente ist ein kommandobasiertes Werkzeug (siehe Abbildung11.5), mit dem man administrative Aufgaben sowie SQL-Anweisungen ausführenkann. Die Funktionalität ist prinzipiell äquivalent zur Console-Komponente, jedochlaufen alle Befehle über die Kommandozeile und nicht innerhalb einer graphischenOberfläche. Das Haupteinsatzgebiet ist somit die interaktive Verarbeitung von Daten-bankoperationen.

���5 ��������������������

Je nach verwendeter Edition des PointBase-Produktes wird das Datenbanksystem inverschiedenen Java-Bibliotheken (.jar-Dateien) geliefert. Jede Bibliothek enthält eineVersionsnummer und eine Typangabe, die aussagt, ob es sich um eine lizenzierte Ver-sion handelt. (Das Kürzel re steht für restricted und kennzeichnet eine Demoversion�während ga general available bedeutet und eine Vollversion kennzeichnet. Tabelle 12.2zeigt die PointBase-Bibliotheken für verschiedene Editionen:

�������������������� �� �%%����

Page 409: Java in Datenbanksystemen

������ %1����($����#������� � ��2

���6 "���������!�����������������������

���6�� ����������������������

Je nach verwendeter PointBase-Edition kann auf verschiedene Art und Weise eineDatenbank entwickelt werden. Die Micro-Edition stellt keinerlei Werkzeuge zur Verfü-gung, die z.B. die graphische Erstellung einer Datenbank ermöglicht hätten. Das ver-wundert nicht, da mit dieser Edition in der Regel Anwendungen für smart devices wieHandys und PDAs (Personal Digital Assistent) entwickelt werden. (In einer solchenUmgebung programmiert der Entwickler direkt eine Datenbankanwendung mit einereigenen schlanken Oberfläche, unter Verwendung der von Micro zur Verfügunggestellten Komponenten wie SQL und der Untermenge von JDBC.) Denkbares Szena-rio wäre z.B. die Programmierung einer Adressenverwaltung für ein Handy odereinen PDA, die dann eine Micro-Datenbank verwendet.

Für die Embedded- und Server-Version stehen mehrere bequemere Möglichkeiten zurVerfügung. Zum einen kann ein Entwickler mittels der Console- (bzw. Commander-)Komponente schnell und einfach eine Datenbank erzeugen, zum anderen kann er auchinnerhalb JDBC-Anwendungen und mit einer beliebigen Entwicklungsumgebung(Borland JBuilder, z.B.) eine PointBase-Datenbank entwickeln. PointBase unterstütztdie gängigsten Java-Entwicklungsumgebungen.

���6�� �����������'���

Im vorherigen Kapitel haben wir gezeigt, wie ein Java-Objekt bei Cloudscape direkt alsDatentyp einer Tabellenspalte angewendet wird und wie dessen Methoden verwendetwerden können (siehe Beispiel 11.2). Dieser Abschnitt zeigt, wie ein Java-Objekt mitPointBase in einer Tabelle abgelegt werden kann.

PointBase unterstützt keine Java-Klassen, die als Spaltentypen verwendet werden kön-nen. Es werden lediglich ByteArrays unterstützt. (Ein ByteArray ist ein Vektor, dessenElement ein Byte ist. Damit stellt ein ByteArray eine Sequenz von Bytes dar.) Mit Hilfe

������������������ ������������

�7%89 '������::;��<�=�>�

���'���?�'������5@��>�

�� �� � '���������::;��<�=�>�

���'���?�'���������5@���>�

8& 8 '������::;��<�=�>�

'�������::;��<�=�>�

&������������������ ��������(�$�

Page 410: Java in Datenbanksystemen

��� ����������� �

geeigneter Methoden können dadurch auch ganze Objekte von einer Datenbank gele-sen und in die Datenbank zurückgeschrieben werden.

Bevor wir das Hauptprogramm darstellen, werden wir die Java-Klasse namens Pro-dukt erörtern, die vom PointBase-Programm verwendet wird. Beispiel 12.1 zeigt dieseKlasse.

Beispiel 12.1

�����������������

��������������������������� ���������� ���

!

������������������������

���������������� � ����

������������� ���� ��

�����������������"#!$

�����������������"%���&'#!

�����������(%���"#�

����$

�����������������"���� � ������������������� ���� �#!

������������� ����)� ����

�������������������)�������

��������������� ��)��� ��

����$

����������� ����*� �"#!������ ��� ���$

�������������� ���+���"#!������ � �����$

�����������������������"#!������ ��������$

������������������,����������"#!������ ��������� ���$

�������������� ������� "#!

������������� �-��������-. ���.-��������-./����������� "�����#.-

���������*� ���-.0 ����������� "�� �#.-1 -�

����$

����������������������2����"2����2���������������#�������

�����0234������

����!

����������%�!

���������������������/����"�����#�

���������������������567" ���#�

���������������������0 �"�� �#�

��������$�������"34������ ��#�!

����������������� ������6����"#�

��������$

����$

���������������������2����"2����0 ����������� #��������0234������

����!

����������%�!

������������������)�� �����/����"#�

������������ ����)�� �����567"#�

�������������� ��)�� �����0 �"#�

��������$�������"34������ ��#�!

����������������� ������6����"#�

Page 411: Java in Datenbanksystemen

������ %1����($����#������� � ���

��������$

����$

������������(%���"%���&'#�!

����������%�!

������������2����0 ����������� �)

����������������� ���2����0 ���������" ���(%��8���%0 ���������"##�

����������������2����"� #�

��������$�������"34������ ��#�!

����������������� ������6����"#�

��������$

����$

����%��&'���(%���"#�!

����������%�!

������������(%��8���%2���������������)� ���(%��8���%2�����������"#�

������������2����2����������������)� ���2����2�����������"���#�

�����������������2����"���#�

���������������������"#�

����������������� �������(%��8���%"#�

��������$�������"34������ ��#�!

����������������� ������6����"#�

����������������� � ����

��������$

����$

$

In Beispiel 12.1 übernimmt ein Konstruktur der Klasse Produkt ein ByteArray undinitialisiert daraus mit Hilfe der neuen Methode setBytes() das erzeugte Objekt. DieKlasse Produkt erweitert die Serializable-Schnittstelle und überschreibt deren beideMethoden writeObject() und readObject(). Diese Methoden ermöglichen es, die wich-tigen Objektdaten in einen Ein- bzw. Ausgabestrom zu schreiben, bzw. von dort zulesen.

Mit Hilfe der Methoden readXXX() und writeXXX() der Klasse ObjectStreams werdendie Inhalte der Produktklasse auf den Objekt-Strom geschrieben bzw. in der gleichenReihenfolge davon gelesen. (Das Objekt wäre in dieser Art im Prinzip identisch mitdem aus dem Cloudscape-Beispiel und könnte genauso dort verwendet werden. DaPointBase jedoch keine Objekt-Serialisierung unterstützt, muss man hier andere Wegegehen.)

Da die Serializable-Schnittstelle private Methoden enthält, ist es nicht möglich, direktvon außen auf diese Methoden zuzugreifen. Deshalb werden die beiden Methoden set-Bytes() und getBytes() benötigt. Die Methode setBytes() übernimmt ein ByteArray underzeugt daraus eine Instanz der Klasse ObjectInputStream, welche anschließend derreadObject()-Methode übergeben wird. Sie wird also dann aufgerufen, wenn dasObjekt mit Daten aus einem ByteArray gefüllt werden soll.

Die getBytes()-Methode hingegen erzeugt eine Instanz der Klasse ByteOutputStream,über die eine Instanz der Klasse ObjectOutputStream gelegt wird. Diese zweite

Page 412: Java in Datenbanksystemen

��� ����������� �

Instanz wird der writeObject()-Methode übergeben, welche dann den Objektinhalt,also die Produktdaten in diesen Strom hineinschreibt. Der mit Daten gefüllte Stromwird nun in ein ByteArray ausgegeben, welcher zurückgegeben wird. Diese Methodewird also immer dann aufgerufen, wenn der Objektinhalt gespeichert werden soll.

Beispiel 12.2 speichert Daten des gleichen Objekts wie im ersten Cloudscape-Beispiel(siehe Beispiel 11.2) in einer PointBase-Datenbank ab, liest sie danach wieder aus undrekonstruiert ein entsprechendes Java-Objekt.

Beispiel 12.2

�������5�������

�������������9����

�����������������

�������������������

��������������� ����/���

!

������������� ���� ��/(*��)�/(5������20+6(8�3�

������� :�����;������ ��<��/(=>��������

�����������?� ����� ��� �)� ����

������������������ �������)� ����

�����������@������������)� ����

�������������������������������������������

������������������������� "���� ����&'#

����!

����������"�A/(5������ ��/������/�����"/(*�##������ �

����������"�"�� �)�/(5������� ���/���(���"/(*�##�))� ���#������ �

����������%

��������!

�������������%������������ �� "-;��� �� � ��/(�2B1 -#�

�����������������)��� �������������� �"#�

�������������������������6�������:����

��������������%!

����������������������4�����"-/@2��68(C3���������-#�

������������$�����"34������ ��#!$

������������������4�����"-?@3863�68(C3���������"�D���0+63,3@�+26

�������������+5CC��@0*8@E�B3E����������;8@(0+8@E"FGG#�#-#�

�������������%������������ �� "-��������=6��������������-#�

�������������������&'���)�! ��

��������������������"-7����� � ���� ��-�H�IJ�K#� ��

�������

Die vorgestellte Programmiermethode in Beispiel 12.2 ist prinzipiell mit jedemDatenbanksystem, das die getArray()/setArray()-Methoden der ResultSet-Klassebzw. den Datentyp BLOB unterstützt, möglich.

POINTBASE

Page 413: Java in Datenbanksystemen

������ %1����($����#������� � ���

��������������������"-7���������-�I�LK�FG#� ����������"-8L=

�������������7���������� ��-�FII�IK�F#$�

��������������������/��� ��� ��� �<������������������ ���� �<�

��������������������������� ��������)��� ��������������� �"-0+�3@6

�������������0+62����������;8C53��"M��M#-#�

���������������"�� ���)G���N���� �����..#

������������!

�������������������������0 �"F����#�

�������������������������(%���"O���&�'���(%���"#�#�

�����������������������4�����5�����"#�

�����������������%������������ �� "��������5�����?�� �"#.-�@����

������������������� ��<�-#�

������������$

���������������8����������� ��� �����

�������������%������������ �� "-1 ;���� �� ������������-#�

�������������%������������ �� "-8�����������������=������ "#=

�������������*��������-#�

���������������)�������4�����P���%"-�3C3?6���������7@2*���������-#�

�����������������"��� �4�"##!

���������������������������)� ����������"#�

����������������������(%���"�����(%���"F##�

�����������������%������������ �� "��#�

������������$

���������������;���� �� ��� ����� ������� �7� ����

�������������%������������ �� "-8���������/��� �Q �����

������������������������ ����������-#�

���������������)�������4�����P���%"-�3C3?6�?R8@DC3+,6R"�������#�7@2*

���������������������-#�

�����������������"��� �4�"##

�����������������%������������ �� "��������� "F##�

���������������/��� � �������� �S��������� ��

�������������%������������ �� "-1 8�������� ��������=*������ ��

�������������S�����-#�

���������������)�������4�����P���%"-�3C3?6���������7@2*���������-#�

�����������������"��� �4�"##!

���������������������������)� ����������"�����(%���"F##�

�����������������%������������ �� "-��+���"#��-�.������+���"#�.�-

�����������������1��������"#��-�.�����������"#�.

�����������������-�1���,����������"#��-�.������,����������"##�

������������$

��������������8������������� ���������������������������

����������������������"#�

�������������� ������"#�

��������$

����������8���<��������S/(?=7�������� ��� �=============

����������������PC=*������ ������ ��������� ���PC34������

�������������"�PC34������ ��#

��������!

������������/(5����������PC34������ "�#�

��������$

�������������"34������ ��#!

Page 414: Java in Datenbanksystemen

��� ����������� �

�������������%������������ �� "-1 ===�5 ��� ����7������===1 -#�

����������������� ������6����"#�

��������$

����$��3 ����� �*��

$

Ausgabe des Beispiels:

;��� �� � ��/(�2B

��������=6��������������

F�@������� ��<�

F�@������� ��<�

F�@������� ��<�

;���� �� �����������

8�����������������=������ "#=*�������

��������7����� � ���� ����������H�IJ�*� ���K

��������7�����������������I�LK�*� ���FG

��������8L=7���������� ����������FII�IK�*� ���F

8���������/��� �Q ����������������� ����������

HT

HG

HI

8�������� ��������=*������ �� �S����

��+���"#��7����� � ���� ��������������"#��H�IJ�������,����������"#��FI�I

��+���"#��7��������������������"#��I�LK������,����������"#��IL�K

��+���"#��8L=7���������� �������������"#��FII�IK������,����������"#��FII�IK

Nach der Herstellung der Verbindung zur Datenbank wird die in Beispiel 12.2 verwen-dete Tabelle produkte gelöscht und danach neu angelegt. Die Tabelle enthält dabeieine Spalte produkt mit den zu speichernden Objektdaten, die als Typ VARBINARYdeklariert sind:

?@3863�68(C3���������"�D���0+63,3@�+26�+5CC��@0*8@E�B3E�

������������������������������;8@(0+8@E"FGG##

Dadurch wird eine Spalte mit einer Datenlänge von 100 Bytes für jedes Produkt reser-viert. Die Produkte werden in einem Vektor abgelegt und bei ihrer Erzeugung gleichmit Werten gefüllt. Um die Produkte in die Datenbank zu speichern, wird eine Instanzder Klasse PreparedStatement verwendet.

Im obigen Beispiel wird mit Hilfe der getBytes()-Methode der Objektinhalt in einenVektor mit Byte-Sequenzen konvertiert und der Instanz der Klasse PreparedStatementüber dessen setBytes()-Methode übergeben:

���������(%���"O���&�'���(%���"#�#�

Im Gegensatz zum Cloudscape-Beispiel, bei dem die Datenbank auch auf die Objekt-methoden zugreifen kann, werden bei PointBase nur die relevanten Daten, die in derKlasse Produkt enthalten sind, in der Datenbank abgelegt. Die Datenbank »weiß« alsobei PointBase nichts von einer Klasse Produkt und deren Eigenschaften.

Page 415: Java in Datenbanksystemen

3� �%%�.� �� ���

Danach wird über eine SELECT-Anweisung die Spalte mit den Produktdaten ausgele-sen. Für jede gefundene Reihe wird eine Instanz der Klasse Produkt ohne Inhalterzeugt, welches dann mit Hilfe der setBytes()-Methode mit den Daten aus der Ergeb-nismenge gefüllt wird:

�����������)� ����������"#�

������(%���"�����(%���"F##��

Das Objekt ist nun vollständig wieder hergestellt und kann am Bildschirm ausgegebenwerden.

PointBase unterstützt auch skalare SQL-Funktionen wie SUBSTRING oder die im Bei-spiel verwendete Funktion CHAR_LENGTH. Diese Funktion liefert die Länge einerZeichenkette zurück. Im Beispiel wird ausgegeben, wie viel Bytes die jeweiligen Pro-duktdaten in der Datenbank belegen.

Der nächste Teil des Beispiels 12.2 zeigt eine kleine Vereinfachung der Objektrekon-struktion:

�����������)� ����������"�����(%���"F##�

Hier wird das rekonstruierte Objekt gleich im Konstruktor mit den Objektdatengefüllt. Im Gegensatz zum Cloudscape-Beispiel können die Methoden der Klasse Pro-dukt nicht direkt in der SELECT-Anweisung angegeben werden, da die Datenbank jakein Objekt, sondern nur dessen Inhalt enthält. Deswegen muss man die Methodendirekt in Java auf dem Objekt anwenden.

���A )�����*���

PointBase weist einige Unterschiede zu Cloudscape auf. Die beiden wichtigsten sind:

� PointBase ist ein relationales Datenbanksystem

� Java-Klassen können nicht als Datentypen von Spalten verwendet werden.

Obwohl PointBase in Java implementiert ist, handelt es sich um ein relationales Daten-banksystem. Das einzige, was PointBase zusätzlich unterstützt, sind die DatentypenBLOB und CLOB.

Ein zweiter wichtiger Unterschied zeigt sich in der Verwendung von Java-Klassen: BeiPointBase ist es nicht möglich, Java-Klassen als Datentypen einer Spalte zu verwen-den. Mit Hilfe von ByteArrays und entsprechenden Methoden ist es jedoch möglich,ganze Objekte aus einer Datenbank zu lesen bzw. solche in die Datenbank zu schrei-ben.

Page 416: Java in Datenbanksystemen
Page 417: Java in Datenbanksystemen

�� ��������

1. Arnold, K.; Gosling J. – The Java Programming Language, Addison-Wesley, 1996.

2. Ashmore, D. – Best Practices for JDBC Programming, Java Developer’s Journal,April 2000.

3. Darby, C. – Optimizing Database Transactions with the JDBC, Java Report, Nov.1998.

4. Dehnhardt, W. – Anwendungsprogrammierung mit JDBC. Datenbanken, Java,Client/Server, Carl Hanser Verlag, 1999.

5. Eckel, B. – Thinking in Java, Prentice Hall, 1998. (Auch Online unter www.bruce-eckel.com)

6. Gulutzan, P.; Pelzer, T. – SQL-99 Complete Really, R&D Books, 2000.

7. Krüger, G. – Go To Java 2, Addison Wesley.

8. Morisseau-Leroy, N. et al. – Oracle 9i SQLJ Programming, Osborne, 2001.

9. O’Neil, P.; O’Neil, E. – Database Principles, Programming and Performance, Mor-gan Kaufmann, 2001.

10. Petkovic, D. – INFORMIX Universal Server, Addison-Wesley, 1998.

11. Price, J. – Java Programming with Oracle SQLJ, O’Reilly, 2001.

12. Saake, G.; Sattler, K. – Datenbanken und Java (JDBC, SQLJ und ODMG), dpunktVerlag, 2000.

13. Shirazi, J. – Java Performance Tuning, O’Reilly, 2000.

Page 418: Java in Datenbanksystemen

��� ������������

14. www-Adresse zu MySQL: www.mysql.com

15. www-Adresse zu MySQL-JDBC-Treiber: http://mmmysql.sourceforge.net/

16. www-Adresse zu Oracle Technical Network mit Entwickler Infos, SQLJ-Translator:http://otn.oracle.com/

17. www-Adresse zu IBM DB2 mit Entwickler Infos und JDBC-Treiber: http://www-4.ibm.com/software/data/db2/udb/

18. www-Adresse zu Informix mit Entwickler Infos und Dokumentation: http://www-4.ibm.com/software/data/informix/ids/

19. www-Adresse zu Java-Dokumentation: http://java.sun.com/docs/

Page 419: Java in Datenbanksystemen

�����

#sql 252.ser 251

Abbildungobjektrelational 402

absolute 224, 227addBatch 232Aliasname 43ALTER TABLE 30Anweisungsklausel 253Anweisungsobjekte 236APPLET 166Applet 162Applet.start() 162AppletViewer 162ArrayDescriptor 192ArrayList 202, 205, 308, 310Attribut 27Ausführungszeit 216AutoCommit 171, 174, 233

batch-Verarbeitung 229Beispieldatenbank 20benannter Iterator siehe bei SQLJ 262BFILE 167BLOB 167, 172Blob.getBinaryStream() 284BLOB.getBytes() 283BLOB.getChunkSize() 283Blob.length() 283BLOB.putBytes() 283Block

anonym 321BufferedReader 156

CALL 162, 273, 275, 348CallableStatement 119, 159, 369CallableStatement.prepareCall() 159CAST 58CharVarray 300Chunk 283Class.forName() 115ClassGenerator 202, 309CLI 39, 245CLOB 167Cloudconnector 386, 389Cloudscape 377

Bibliothek 391eingebettet 388in Client/Server 389

Cloudsync 385Cloudview 383, 384Commander 408COMMIT 174commit 236COMMITTED READ 177CONCUR_READ_ONLY 125CONCUR_UPDATEABLE 125Connection 117Connection.commit() 174Connection.createStatement() 123Connection.prepareStatement() 156Connection.rollback() 174Console 407CREATE CAST 54CREATE DISTINCT TYPE 55CREATE FUNCTION 276, 340, 346, 364

PARAMETER STYLE JAVA 362CREATE OBJECT TYPE 42CREATE OPAQUE TYPE 54

Page 420: Java in Datenbanksystemen

��� �����

CREATE OR REPLACE PROCEDURE 161

CREATE PROCEDURE 159, 340,347, 363EXTERNAL NAME 364LANUAGE JAVA 363

CREATE ROW TYPE 57, 209, 393CREATE TABLE 29, 133CREATE TRIGGER- 356CREATE TYPE 42, 191, 289CREATE VARRAY 46CREATE VARRAY TYPE 299CREATE VIEW 34currentTimeMillis 217Cursor 247

Nicht-Scroll 224Scroll 224

Customizer 251

DatabaseMetaData 143Datenbankdefinition 17Datenbankdesign 23Datenbankzugriffe

Optimierung 220Datenintegrität 19Datentyp

benutzerdefiniert 212BLOB 415CLOB 415REF 289, 315, 324VARRAY 296

Datenunabhängigkeit 18DBUtils 136DBUtils.connectDataBase() 139DBUtils.initDatabaseDriver() 139DBUtils.showSQLException() 139DBUtils.showWarnings() 139DDL 29DDL-Anweisung 245DefaultContext 314DELETE 34, 122DELETE FROM 159DISTINCT 70DML 29Driver 115Driver.registerDriver() 115DriverManager 117

DriverManager.getConnection() 118DROP TABLE 30DROP TYPE 44DROP VIEW 34dropjava 344

E/R-Modell 26Edition

Embedded 404Micro 403Server 404

Embedded 404EMPTY_BLOB 282empty_blob() 172Ergebnismenge 123ESCAPE 129ESQL 245executeBatch 229, 232, 321executeQuery 226

Fehlerbehandlung 130FENCED 363FETCH 269, 355, 374FETCH_FORWARD 239FETCH_REVERSE 240FETCH_UNKNOWN 240FileInputStream 171FOR EACH ROW 356FOR UPDATE 273Framework-Modus 397Funktion

gespeichert 342

GenericStruct 211Gespeicherte Prozeduren 38getARRAY 191getSQLTypeName 204, 210

HashSet 310HLI 39Host-Ausdruck

IN 254INOUT 254modus 254

Page 421: Java in Datenbanksystemen

����� ��

OUT 254Syntax 254

Host-Variable 247

Informationsschema 36Informix 378INSERT 32, 171InstantDB 377isNull 362Isolierungsstufe 216Isolierungsstufen 177Iterator 247

benannt 264Deklarationssyntax 270positioniert 268

jdbc.drivers 115Jeevan 377Join 324Join-Operator 51jpub 293Jpublisher 293

Klasse 186Klassen-Schemaobjekt 345Kollektion 305

VARRAY 289Kollektionen 45, 181, 198Kollektionsdatentyp 60Komponentenklasse-Beziehung 51konkurrierender Datenzugriff 19

LIKE 129LIST 62, 198, 308Liste 198loadjava 344LOB 167Logik

Daten 379Geschäfts 379

Lokator 282LONGBLOB 287LUCID 378

Menge 198Mengenorientierung 247Metadaten 35, 143Micro 403MULTISET 61

nativer Treiber 109NESTED TABLE 47Normalisierung 24NULL-Wert 362

ObjectOutputStream 411ObjectStreams 411Objekt

serverseitig 339Objekte

serialisiert 402Objekttyp 42, 56, 181, 289ODBC 107ONLY 69Optimierer 216oracle.sql 191OracleConnection.setDefaultRow-

Prefetch 331OraclePreparedStatement 188, 192, 212OracleResultSet 172, 186, 212Ozone 377

Performance 317PL/SQL 339PointBase 377, 401

Bibliotheken 408Commander 408Server 406

Positioned update 150positionierter Iterator siehe bei SQLJ 266PreparedStatement 119, 154, 352PreparedStatement.getMoreResults() 15

9prepareStatement 222Pro*C 348processARRAY 197processSTRUCT 197

Page 422: Java in Datenbanksystemen

��� �����

processStruct 211Programm

gespeichert 360Prozedur

gespeichert 328gespeicherte 339

readObject 411readSQL 187, 204, 210REF 70, 181REF-Datentyp 50Reihentyp 56, 198, 305relative 224, 227REPEATABLE READ 177Ressource-Schemaobjekt 345result set concurrency 124result set type 124ResultSet 122, 141ResultSet.deleteRow() 154ResultSet.getString() 143ResultSet.getXXX() 127ResultSet.next() 122ResultSet.wasNull() 123resultSetConcurrency 151ResultSetMetaData 146ResultSetMetaData.getColumnCount()

150ResultSetMetaData.getColumnDisplay

Size() 153ResultSet-Methoden 125RETURN 348ROLLBACK 174ROW 202row prefetching 331

Satzorientierung 247Schnittstellen 18Scroll-Cursor 148SELECT 31, 164SELECT INTO 261Semantikanalyse 252SERIALIZABLE 177Serializable 411

SERIALIZE 397SET 61, 198, 254setARRAY 192setDefaultRowPrefetch 333setFetchDirection 239setFetchSize 240setREF 192skalare Funktion 129smart device 409Sperren 216SPL 339SQL*Plus 348SQL99 41SQLData 187SQLException 130SQLException-Methoden 130SQLJ

Batchdatei 256benannter Iterator 262DELETE mit Iterator 270dynamisch 248Kommando 255Onlinechecking 257Optionen 255positionierter Iterator 266Profil 251ResultSet 269SELECT mit Iterator 262SELECT ohne Iterator 259statisch 248, 251UPDATE mit Iterator 270Vorübersetzer 246

SQLWarning 131SQL-Wrapper 346Statement 119, 236Statement.execute() 120, 139Statement.executeQuery() 121Statement.executeUpdate() 121Statement.getMoreResults() 120StringWriter 173STRUCT 205Struct 202, 209, 211Systemeigenschaft 115Systemkatalog 35

Page 423: Java in Datenbanksystemen

����� ��

Tabellegeschachtelt 289, 300Hierarchie 311

Tabelleneigenschaften 148Tabellenhierarchie 66Tabellenhierarchien 212Transaktion

explizit 232implizit 233

Transaktionen 173Transaktionsprotokoll 173Translator 250Treiberinformationen 144Treibermanager 107, 113Treibertypen 109Trigger 339, 355

AFTER 356BEFORE 356

TYPE_FORWARD_ONLY 124TYPE_SCROLL_INSENSITIVE 125TYPE_SCROLL_SENSITIVE 125Typhierarchie 66Typhierarchien 205Typkonvertierung 178Typumwandlung 178

UDF 361UNCOMMITTED READ 177UNDER 57, 67UniSync 406UPDATE 33, 139, 159, 176, 262URL 117

VALUES 276, 355VARRAY 47Vektor 289Vektoren 46Verbindungsherstellung 134View 34

Wrapper 346writeObject 411writeSQL 187, 204, 210

Zuweisungsklausel 253


Recommended