Softwareentwicklung mit JAVA EE Grundlagen: Datenbankprogrammierung
Literatur T. Kudraß (Hrsg.): Taschenbuch Datenbanken, Hanser, 2007 DB-Programmierung-2
Einbettungstechniken Einbettung in 3GL Embedded SQL Aufrufschnittstelle Call-Level-Interface (CLI) prozedurale Schnittstelle Sprachen der 4. Generation DB-Programmierung-3
Einbettungsarten statische Einbettung Die DB-Anweisung steht bei der Programmentwicklung fest. dynamische Einbettung Die DB-Anweisung wird zur Laufzeit erst festgelegt. Beispiel: Anfragewerkzeuge, Browser DB-Programmierung-4
Probleme der Einbettung Programmiersprachen kennen keinen Typ "Relation"! Die Verarbeitung von Daten erfolgt satzorientiert. Impedance mismatch Programmiersprachen kennen keine NULL-Werte. DB-Programmierung-5
Das Cursor-Konzept Eine Relation wird in der Programmiersprache als Liste behandelt. Ein Cursor ist ein Iterator über eine Liste von Tupeln. Zeiger auf ein Element einer Liste. Cursor können gelesen und weiter gesetzt werden (FETCH NEXT). Implementierungsabhängig gibt es noch weitere Positionierungsoperationen. DB-Programmierung-6
Veranschaulichung: Cursor-Konzept Satzweise Verarbeitung C-Anwendungsprogramm Datenbank Cursor Relation DB-Programmierung-7
Cursor Deklaration Syntax: <cursor_decl> := DECLARE <cursor_name> [ INSENSITIVE ] [ SCROLL ] CURSOR FOR <cursor_spec> <cursor_spec> := <table_expr> [ ORDER BY { <column_name>//, } ] [ FOR { READ ONLY UPDATE [ OF { <column_name>//, } ] } ] Beispiel: DECLARE c1 CURSOR FOR SELECT Name FROM Angestellte WHERE AbtNr = 'Einkauf' DB-Programmierung-8
Cursor - Zusatz: INSENSITIVE INSENSITIVE Es wird auf einer Kopie der ausgewählten Daten gearbeitet. Änderungen auf den einmal ausgewählten Daten sind für den Cursor unsichtbar. Ohne INSENSITIVE ist es abhängig von der jew. Implementierung, ob Änderungen sichtbar sind, oder nicht. DB-Programmierung-9
Cursor - Zusatz: SCROLL Normalerweise kann nur einmal sequentiell durch die Ergebnismenge gegangen werden. FETCH NEXT SCROLL Erlaubt beliebiges vor- und zurückbewegen: FETCH NEXT FETCH PRIOR FETCH FIRST FETCH LAST FETCH ABSOLUTE n FETCH RELATIVE n DB-Programmierung-10
Cursor - Zusatz: FOR UPDATE Dieser Zusatz ermöglicht das Verändern von Daten beim Iterieren (Positioned Update). Beispiel: DECLARE c1 CURSOR FOR SELECT Name FROM Angestellte WHERE AbtNr = 'Einkauf' FOR UPDATE UPDATE Angestellte SET gehalt = gehalt + 50 WHERE CURRENT OF c1 UPDATE Angestellte SET gehalt = gehalt + 50 WHERE persnr = 4711 DELETE Angestellte WHERE CURRENT OF c1 DB-Programmierung-11
Behandlung von NULL-Werten Einsatz von Indikatoren: Für jeden Ein-/Ausgabeparameter wird ein zusätzlicher (boolscher) Parameter übergeben. Diese Zusatzparameter enthalten Informationen, ob es sich bei dem zugeordneten Parameter um einen NULL-Wert handelt. DB-Programmierung-12
Einbettung in 3 GL (Embedded SQL) Erfordert Vorübersetzer (Precompiler): Programme mit eingebetteten DB-Kommandos werden in übersetzungsfähige Programme transferiert. Die erforderlichen Precompiler werden von den Datenbankherstellern geliefert. Ein Programm enthält also Anweisungen aus zwei verschiedenen Programmiersprachen. Die Einbettung in einige wichtige Sprachen (C, Fortran, Cobol) wurde mit SQL92 genormt. DB-Programmierung-13
Einbettung in 3 GL - Technik Kennzeichnung der DB-Befehle durch das Schlüsselwort: EXEC SQL. Zusätzlich zu den ausführbaren Kommandos kommen deklarative. Spezielle Kommandos: DECLARE, OPEN, FETCH. SQL Statements können sich auf Variablen der Programmiersprache beziehen: host variables Diese werden in der Anfrage durch einen Doppelpunkt gekennzeichnet. DB-Programmierung-14
Einbettung in 3 GL - Übergabe Deklaration von Host-Variablen: EXEC SQL BEGIN DECLARE SECTION; name CHAR(10); abtnr CHAR(10); EXEC SQL END DECLARE SECTION; Binden von Host-Variablen Welche Hostvariablen zur Ein-/Ausgabe von Daten verwendet werden, muss mitgeteilt werden: OPEN: Eingabevariablen FETCH: Ausgabevariablen DB-Programmierung-15
Einbettung in 3 GL - Cursorzugriff Deklaration eines Cursors: EXEC SQL DECLARE cu1 CURSOR FOR SELECT Name FROM Angestellte WHERE AbtNr =?; Öffnen des Cursors: EXEC SQL OPEN cu1 USING :abtnr; Auslesen der Daten: EXEC SQL FETCH cu1 INTO :name; Schließen des Cursors: EXEC SQL CLOSE cu1; DB-Programmierung-16
Dynamische Einbettung in 3 GL Deklaration einer Variablen für die Anfrage: EXEC SQL BEGIN DECLARE SECTION; anfrage_text CHAR(256) varying; pers_nr CHAR(10); EXEC SQL END DECLARE SECTION; Festlegung der Anfrage anfrage_text = "DELETE FROM Angestellte WHERE PersNr =?"; Bekanntmachen der Anfrage EXEC SQL PREPARE anfrage FROM :anfrage_text ; Ausführen der Anfrage EXEC SQL EXECUTE anfrage USING :pers_nr ; DB-Programmierung-17
Einbettung in 3 GL - Schleifensteuerung Reaktion auf spezielle Situationen: EXEC SQL WHENEVER <Bedingung> <Aktion> <Bedingung> := { NOT FOUND SQLWARNING SQLERROR } <Aktion> := { CONTINUE GOTO <label> STOP DO <routine> } DB-Programmierung-18
Einbettung in 3 GL - Beispiel Embedded SQL EXEC SQL BEGIN DECLARE SECTION; name CHAR(50); abtnr INT; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE cu1 CURSOR FOR SELECT Name FROM Angestellte WHERE abtnr =?; EXEC SQL OPEN cu1 USING :abtnr; for (;;) { EXEC SQL FETCH cu1 INTO :name; EXEC SQL WHENEVER NOT FOUND GOTO FERTIG; printf ("Name des Angestellten: %s", name); } FERTIG: printf ("Alle ausgegeben! \n"); EXEC SQL CLOSE cu1; DB-Programmierung-19
Verarbeitung von Embedded SQL C-Quellcode mit Embedded SQL Precompiler Generierter C-Quellcode C- Compiler DB-Library Linker Compilierter Code Ausführbares Programm DB-Programmierung-20
SQLJ: Embedded SQL für Java // Iteratorklasse definieren #sql iterator It_typ ( String vname, String nname ); It_typ it; // Abfrage durchführen und Iterator dem Ergebnis zuweisen #sql it = { SELECT Vname, NName FROM Angestellte WHERE abtnr = :abtnr }; while (it.next()) { System.out.println ("Name des Angestellten : " + it.vname() + ' ' + it.nname()); } it.close(); System.out.println ("Alle ausgegeben!"); DB-Programmierung-21
Aufrufschnittstellen Es werden Funktionen aus einer Bibliothek verwendet. Die DB-Anfragen werden in der Regel in Textvariablen übergeben. Dynamische Einbettung Beispiele: OCI (Oracle Call Interface) ODBC (Open Database Connectivity) JDBC (Java Database Connectivity) DB-Programmierung-22
Aufrufschnittstellen (II) Fehlerbehandlung, Zustandsinformation Entweder über spezielle Funktionsaufrufe Oder über spezielle Variablen Beispiel: OCI Logon Data Area (LDA): Spezielle Variable dieses Typs enthält Statusinformationen über die aktuelle Verbindung. Cursor Data Area (CDA): Enthält Informationen über den einen Cursor, wie z.b. Anzahl gelesener Sätze, Gültigkeit, letzter Returncode,... DB-Programmierung-23
Aufrufschnittstellen - oci Ausschnitt aus OCI-C-Programm: char * seltext = "SELECT Name FROM Angestellte WHERE AbtNr = 'Einkauf'"; /* Anfragetext */ Cda_Def cda; /* Cursor Variable */ char name[50]; /* Platz für das Ergebnis */ oopen (&cda, &lda, 0, -1, -1, 0, -1); oparse (&cda, seltext, -1, 0, 2); odefin (&cda, 1, name, 50, STRING_TYPE, -1, 0, 0, -1, -1, 0, 0); oexec (&cda); for (int rc = ofetch(&cda); rc!= 0; rc = ofetch(&cda)) { printf ("Name des Angestellten: %s", name); } printf ("Alle ausgegeben! \n"); DB-Programmierung-24
Aufrufschnittstellen - jdbc Ausschnitt aus jdbc-programm: String seltext = "SELECT Name FROM Angestellte" + "WHERE AbtNr = 'Einkauf'"; Statement stmt = conn.createstatement(); ResultSet rset = stmt.executequery (seltext); while ( rset.next() ) { System.out.println( "Name des Angestellten: " + rset.getstring("name") ); } System.out.println ("Alle ausgegeben!"); rset.close(); DB-Programmierung-25
jdbc Treiber & Verbindung Vor Ausführung des o.a. Programms: import java.sql.*; // Laden der Klasse bewirkt Registrierung Class.forName ("org.gjt.mm.mysql.driver"); // DB-spezifische Verbindungsinfo String cs = "jdbc:mysql:<host>:<port>/<database>"; DriverManager.getConnection(cs+"?user="+un+"&password="+pw); Connection conn = DriverManager.getConnection (); DB-Programmierung-26
Einbettung in 4 GL 4GL - Fourth Generation Language Datenbanksprache Programmiersprache mit integriertem Datenbanktypkonzept Beispiele: Natural (Software AG) ABAP/4 (SAP AG) Gupta SQL PowerBuilder (Sybase) PL/SQL (Oracle)... DB-Programmierung-27
Einbettung in 4 GL Merkmale: Einheitliche Sprache zur Bearbeitung von Daten im Programm und in der Datenbank. Mengenorientierte Verarbeitung möglich. IdR Tabellen als Programmiersprachentyp. Oft: Integrierte Möglichkeiten zur grafischen Darstellung. DB-Programmierung-28
Einbettung in 4 GL - Beispiel Programmbeispiel ABAP/4: Tables Angestellte. Data name LIKE Angestellte-Name. SELECT Name FROM Angestellte INTO name WHERE AbtNr = 'Einkauf'. WRITE: / 'Name des Angestellten: ', name. ENDSELECT. WRITE: / 'Alle ausgegeben! '. DB-Programmierung-29
Einbettung in 4 GL - Beispiel2 ABAP/4 mit internen Tabellen: Tables Angestellte. Data ntab LIKE TABLE OF Angestellte-Name. SELECT Name FROM Angestellte INTO TABLE ntab WHERE AbtNr = 'Einkauf'. LOOP AT ntab. WRITE: / 'Name des Angestellten: ', ntab-name. ENDLOOP. WRITE: / 'Alle ausgegeben! '. DB-Programmierung-30
Einbettung in 4 GL - Beispiel 3 Analoge Operationen sind auf Programm- und Datenbanktabellen möglich: Tables Angestellte. Data angtab LIKE TABLE OF Angestellte. SELECT * FROM Angestellte INTO TABLE angtab. LOOP AT angtab WHERE AbtNr = 'Einkauf'. WRITE: / 'Name des Angestellten: ', angtab-name. ENDLOOP. WRITE: / 'Alle ausgegeben! '. DB-Programmierung-31