9. Anwendungsprogrammierschni4stellen Vorlesung "Informa;onssysteme" Sommersemester 2015 Gliederung § Kopplung mit einer Wirtssprache • Übersicht und Aufgaben § Eingebe4etes sta;sches SQL • Cursor-­‐Konzept • SQL-­‐Programmiermodell • Ausnahme-­‐ und Fehlerbehandlung § Aspekte der Anfrageauswertung • Aufgaben bei der Anfrageauswertung • Vorbereitung und Übersetzung § Dynamisches SQL • Eingebe4etes dynamisches SQL § CLI und ODBC • Call-­‐Level-­‐Interface • Open Data Base Connec;vity (ODBC) § DB-­‐Zugriff aus Java-­‐Programmen • DB-­‐Zugriff via JDBC • SQLJ Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 2 Kopplung mit einer Wirtssprache Kopplungsvarianten Einbettung von SQL in eine Wirtssprache Call-Schnittstelle Call Level Interface (CLI) (z.B. ODBC, JDBC) statisch (static SQL) Integrierte Sprachen bzw. Spracherweiterungen - Persistente Programmiersprachen - DB-Programmiersprachen dynamisch (dynamic SQL) § Einbe4ung von SQL (Embedded SQL, ESQL) • Spracherweiterung um spezielle DB-­‐Befehle (EXEC SQL ...) • komfortablere Programmierung als mit CLI § Sta;sche Einbe4ung • Vorübersetzer (Precompiler) wandelt DB-­‐Aufrufe in Prozeduraufrufe um • Nutzung der normalen PS-­‐Übersetzer für umgebendes Programm • SQL-­‐Anweisungen müssen zur Übersetzungszeit feststehen • im SQL-­‐Standard unterstützte PS: C, COBOL, FORTRAN, Ada, PL1, Pascal, MUMPS, Java § Dynamische Einbe4ung • Konstruk;on von SQL-­‐Anweisungen zur Laufzeit § Call-­‐Schni4stelle (prozedurale Schni4stelle, CLI) • DB-­‐Funk;onen werden durch Bibliothek von Prozeduren/Funk;onen/Klassen realisiert • Anwendung enthält lediglich API-­‐Aufrufe Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 3 Kopplung mit einer Wirtssprache (2) § Wünschenswert sind Mehrsprachenfähigkeit und deskrip;ve DB-­‐ Opera;onen (mengenorien;erter Zugriff) § Rela;onale AP-­‐Schni4stellen (API) bieten diese Eigenschaeen, erfordern jedoch Maßnahmen zur Überwindung der sog. Fehlanpassung (impedance mismatch) § Kernprobleme der API bei konven;onellen Programmiersprachen • Konversion und Übergabe von Werten • Übergabe aktueller Werte von Wirtssprachenvariablen (Parametrisierung von DB-­‐Opera;onen) • DB-­‐Opera;onen sind i. allg. mengenorien;ert: Wie und in welcher Reihenfolge werden Zeilen/Sätze dem AP zur Verfügung gestellt? ➥ Cursor-­‐Konzept AWP satzorientiert AWP-Typsystem DBS mengenorientiert DBS-Typsystem Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 4 Eingebe4etes sta;sches SQL § Anbindung einer SQL-­‐Anweisung an die Wirtssprachen-­‐Umgebung • SQL-­‐Anweisungen werden durch exec sql eingeleitet und durch spezielles Symbol (z.B. “;”) beendet, um dem Compiler eine Unterscheidung von anderen Anweisungen zu ermöglichen • Verwendung von AP-­‐Variablen (Host-­‐Variablen) in SQL-­‐ Anweisungen verlangt Deklara;on innerhalb eines declare sec;on-­‐Blocks sowie Angabe des Präfix “:” innerhalb von SQL-­‐ Anweisungen • Kommunika;onsbereich SQLCA (Rückgabe von Statusanzeigern u.ä.) • Übergabe der Werte einer Zeile mit Hilfe der INTO-­‐Klausel - INTO target-­‐commalist (Variablenliste des Wirtsprogramms) - Anpassung der Datentypen (Konversion) • Aurau/Abbau einer Verbindung zu einem DBS: connect/ disconnect Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 5 Eingebe4etes sta;sches SQL – Beispiel für C exec sql include sqla; /* SQL Communication Area */ main () { exec sql begin declare section; char X[3] ; int GSum; exec sql end declare section; exec sql connect to dbname; exec sql insert into Pers (Pnr, Name) values (4711, ‘Ernie’); exec sql insert into Pers (Pnr, Name) values (4712, ‘Bert’); printf ("Anr?") ; scanf ("%s", X); exec sql select sum (Gehalt) into :GSum from Pers where Anr = :X; /* Es wird nur ein Ergebnissatz zurückgeliefert */ printf (“Gehaltssumme: %d\n”, GSum) exec sql commit work; exec sql disconnect; } Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 6 Cursor-­‐Konzept § Cursor-­‐Konzept zur satzweisen Abarbeitung von Ergebnismengen • Trennung von Qualifika;on und Bereitstellung/Verarbeitung von Zeilen • Cursor ist ein Iterator, der einer Anfrage zugeordnet wird und mit dessen Hilfe die Zeilen der Ergebnismenge einzeln (one tuple at a *me) im Programm bereitgestellt werden • Wie viele Cursor können im AWP sein? § Cursor-­‐Deklara;on DECLARE cursor CURSOR FOR table-exp [ORDER BY order-item-commalist] Informa;onssysteme 2015 DECLARE C1 CURSOR FOR SELECT Name, Gehalt, Anr FROM Pers WHERE Anr = ‘K55’ ORDER BY Name; Kapitel 9: Anwendungsprogrammierschni4stellen 7 Cursor-­‐Konzept (2) § Cursor-­‐Deklara;on DECLARE C1 CURSOR FOR SELECT Name, Gehalt, Anr FROM Pers WHERE Anr = ‘K55’ ORDER BY Name; § Opera;onen auf einen Cursor C1 • OPEN C1 • FETCH C1 INTO :Var1, :Var2, …, :Varn • CLOSE C1 § Reihenfolge der Ergebniszeilen • systembes;mmt • benutzerspezifiziert (ORDER BY) Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen C1 8 Veranschaulichung der Cursor-­‐Schni4stelle Cursor-Deklation in AWP: DECLARE C1 CURSOR FOR SELECT * FROM PERS WHERE ANR > ’30’ ORDER BY PNAME ASC AWP in satzorientierter Programmiersprache 1. Anfrage (OPEN C1) 3. Zeile sequentiell holen (Fetch C1) und verarbeiten 4. Cursor schließen (Close C1) 2. Anfrage auswerten Ergebniszeile im Cursor bereitstellen mengenorientiertes DBS DB • Informa;onssysteme 2015 • Kapitel 9: Anwendungsprogrammierschni4stellen • 9 Beispielprogramm in C (vereinfacht) exec sql begin declare section; char X[50], Y[3]; exec sql end declare section; exec sql declare C1 cursor for select Name from Pers where Anr = :Y; § Anmerkungen • DECLARE C1 ... ordnet der Anfrage einen Cursor C1 zu • OPEN C1 bindet die printf(“Bitte Anr eingeben: \n”); Y); Werte der Eingabevariablen scanf(“%d”, exec sql open C1; while (sqlcode == OK) • Systemvariable SQLCODE { zur Übergabe von exec sql fetch C1 into :X; printf(“Angestellter %d\n”, X); Fehlermeldungen } exec sql close C1; (Teil von SQLCA) § Wann wird die Ergebnismenge angelegt? • lazy: schri4haltende Auswertung durch das DBS? Verzicht auf eine explizite Zwischenspeicherung ist nur bei einfachen Anfragen möglich • eager: Kopie bei OPEN? Ist meist erforderlich (ORDER BY, Join, Aggregat-­‐Funk;onen, ...) Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 10 Datenänderungen mit Cursor § Aktualisierung mit Bezugnahme auf eine Posi;on • Wenn die Zeilen, die ein Cursor verwaltet (ac;ve set), eindeu;g Zeilen einer Tabelle entsprechen, können sie über Bezugnahme durch den Cursor geändert/gelöscht werden. è Änderbarkeit analog zu änderbaren Sichten definiert! • Keine Bezugnahme bei INSERT möglich ! while (sqlcode == ok) { positioned-update ::= exec sql fetch C1 into :X; UPDATE table SET update-assignment-commalist /* Berechne das neue Gehalt in Z /* CURRENT OF cursor WHERE exec sql update Pers Positioned-delete ::= set Gehalt = :Z DELETE FROM table where current of C1; } WHERE CURRENT OF cursor § Cursor kann explizit als "read only" bzw "updatable" deklariert werden (à Op;mierungspoten;al für DBMS) • Beispiel: DECLARE C1 CURSOR FOR SELECT ... FOR READ ONLY Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 11 SQL-­‐Programmiermodell für Mengenzugriff 1) ein Cursor: π, σ, ⋈, ∪, -, γ, sort, ... 2) C1 3) C1 Verknüpfung der gesuchten Zeilen im AP C2 C3 positionsbezogene Aktualisierung INTO C1 4) mehrere Cursor: Variable Update, Delete abhängige Cursor C1 Wert11 Wert1 C2 Wert12 Wert2 Wert13 C2 .. . Informa;onssysteme 2015 C3 C3 C3 Wert21 .. . Kapitel 9: Anwendungsprogrammierschni4stellen 12 Weitere Cursor-­‐Eigenschaeen und Opera;onen § Holdable Cursor • Cursor werden spätestens bei Ende der Transak;on geschlossen • dies läßt sich mit der Op;on WITH HOLD verhindern! - Beispiel: DECLARE C1 CURSOR WITH HOLD FOR SELECT ... § Scrollable Cursor • SCROLL-­‐Op;on erlaubt flexible Posi;onierung beim FETCH - NEXT, PRIOR, FIRST, LAST, ABSOLUTE n, RELATIVE n - Beispiel: DECLARE C1 SCROLL CURSOR FOR SELECT ... • NO SCROLL (Default-­‐Einstellung): nur NEXT möglich erstes Element nächstes Element aktuelles Element fetch first erstes Element Cursor fetch absolute 2 fetch fetch prior aktuelles Element Cursor fetch next fetch relative 2 fetch last Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 13 Weitere Cursor-­‐Eigenschaeen und Opera;onen (2) § Cursor-­‐Seman;k bei gleichzei;gen "signifikanten" Änderungen der gleichen Transak;on • Beispiel: Anwendungsprogramm - öffnet SCROLL CURSOR C1 über alle Angestellten, die in keinem Projekt mitarbeiten - weist (aufgrund Benutzereingaben) einigen Angestellten ein Projekt zu (INSERT INTO Mitarbeit ...) • Frage: werden solche Änderungen in den Inhalten der betroffenen Cursor sichtbar? § Op;onen für Cursor-­‐Sensi;vität • INSENSITIVE: Änderungen werden nicht sichtbar (Cursor ist automa;sch read-­‐only!) • SENSITIVE: Änderungen müssen sichtbar gemacht werden • ASENSITIVE: sichtbare Änderungen vom DBMS festgelegt Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 14 Wirtssprachen-­‐Einbe4ung und Übersetzung § Direkte Einbe4ung • keine syntak;sche Unterscheidung zwischen Programm-­‐ und DB-­‐ Anweisungen • DB-­‐Anweisung wird als Zeichenke4e A ins AP integriert, z. B. exec sql open C1 • verlangt Maßnahmen bei der AP-­‐Übersetzung, typischerweise Einsatz eines Vorübersetzers PC (Precompiler) § Aufrueechnik DB-­‐Anweisung wird durch expliziten Funk;onsaufruf an das Laufzeitsystem des DBMS übergeben, z. B. CALL DBS (‘SELECT SUM(Gehalt) into :Gsum … ') • Es sind prinzipiell keine DBMS-­‐spezifischen Vorkehrungen bei der AP-­‐Übersetzung erforderlich! • Verschiedene Formen der Standardisierung: Call-­‐Level-­‐Interface (CLI), JDBC Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 15 Von der Übersetzung bis zur Ausführung § Vorübersetzung des AP • DBS-­‐sei;ge Vorbereitung: Analyse und Op;mierung der SQL-­‐Anweisungen und Erstellung eines Zugriffsmoduls im DB-­‐Katalog • Ersetzen aller Embedded-­‐SQL-­‐Anweisungen durch Programmiersprachen-­‐spezifische DBS-­‐Aufrufe • Erzeugung eines „SQL-­‐freien“ Programmes in der Programmiersprache § Übersetzung des AP • Umwandlung in Maschinencode (Objektmodul) und Abspeicherung in Objektbibliothek • SQL-­‐Anweisungen für Compiler nicht mehr sichtbar § Binden • Zusammenfügen aller Objektmodule zu lauffähigem Programm • Hinzufügen des SQL-­‐Laufzeitsystems § Laden und Ausführen • Laden des ausführbaren Programms in den Speicher • Anbinden des Zugriffsmoduls aus DB-­‐Katalog und automa;sche Überprüfung seiner Gül;gkeit • Programmstart Embedded-SQLProgramm (z.B. in C) SQL-Precompiler DatenbankKatalog C-Programm (C und DBS-Aufrufe) Zugriffsmodul C-Compiler Programmbibliothek Programmteil in Maschinencode Linker Ausführbares Programm (Lademodul) Loader Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 16 Anfrageverarbeitung -­‐ Überblick Anfrage Analyse Syntaktische Analyse Semantische Analyse (Zugriffs- und Integritätskontrolle) Anfragegraph Optimierung Standardisierung Vereinfachung Anfragestrukturierung Anfragetransformation Ausführungsplan Codegenerierung Ausführung Code-Generierung Ausführungskontrolle Anfrageergebnis Bereitstellung Informa;onssysteme 2015 Bereitstellung in Programmierumgebung Kapitel 9: Anwendungsprogrammierschni4stellen 17 Übersetzung, Op;mierung und Codegenerierung § DB-­‐Anweisung liegt als Zeichenke4e vor • Bei Einsatz eines Interpreters fällt der folgende Aufwand zur Laufzeit an • Vorübersetzung verschiebt die „Vorbereitung“ in die Übersetzungszeit § Erforderliche Verarbeitungsschri4e bis zur Auswertung: 1. Lexikalische und syntak;sche Analyse - Erstellung eines Anfragegraphs (AG) als Darstellung für nachfolgende Schri4e - Überprüfung auf korrekte Syntax (Parsing) 2. Seman;sche Analyse - - - - Feststellung der Existenz/Gül;gkeit der referenzierten Tabellen/Sichten/A4ribute Einsetzen der Sichtdefini;onen in den AG Ersetzen der externen durch interne Namen (Namensauflösung) Konversion vom externen Format in interne Darstellung 3. Zugriffs-­‐ und Integritätskontrolle (Sollen aus Leistungsgründen, soweit möglich, schon zur Übersetzungszeit erfolgen) - Generierung von Laufzeitak;onen für wertabhängige Zugriffskontrolle - Durchführung einfacher Integritätskontrollen (Formatkontrolle, Datentypkonversion) - Generierung von Laufzeitak;onen für komplexere Kontrollen Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 18 Übersetzung, Op;mierung und Codegenerierung (2) 4. Standardisierung und Vereinfachung dienen der effek;veren Übersetzung und frühzei;gen Fehlererkennung - Überführung des AG in eine Normalform - Elimina;on von Redundanzen 5. Restrukturierung und Transforma;on - Restrukturierung: globale Verbesserung des AG durch Anwendung von heuris;schen Regeln (algebraische Op;mierung) - Transforma;on: Ersetzung und ggf. Zusammenfassen der logischen Operatoren durch Planoperatoren (nicht algebraische Op;mierung) -­‐ meist sind mehrere Planoperatoren als Implemen;erung eines logischen Operators verfügbar - Bes;mmung alterna;ver Zugriffspläne (nicht-­‐algebraische Op;mierung): Meist sind viele Ausführungsreihenfolgen oder Zugriffspfade auswählbar - Bewertung der Kosten und Auswahl des güns;gsten Ausführungsplanes è Schri4e 4 + 5 werden als Anfrageop;mierung zusammengefasst 6. Code-­‐Generierung - Generierung eines zugeschni4enen Programms für die (SQL-­‐) Anweisung - Erzeugung eines ausführbaren Zugriffsmoduls - Verwaltung der Zugriffsmodule in einer DBMS-­‐Bibliothek è Mehr zu diesem Thema in der Vorlesung "Datenbanksysteme" Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 19 Anfrageverarbeitung -­‐ Kostenaspekte Anfrage Analyse Syntaktische Analyse Semantische Analyse (Zugriffs- und Integritätskontrolle) Laufzeit bei keiner Vorbereitung Anfragegraph Optimierung Standardisierung Vereinfachung Anfragestrukturierung Anfragetransformation Ausführungsplan Codegenerierung Ausführung Code-Generierung Ausführungskontrolle Anfrageergebnis Bereitstellung Informa;onssysteme 2015 Übersetzungszeit Laufzeit bei maximaler Vorbereitung Bereitstellung in Programmierumgebung Kapitel 9: Anwendungsprogrammierschni4stellen 20 Dynamisches SQL § Festlegen/Übergabe von SQL-­‐Anweisungen zur Laufzeit • Benutzer stellt Ad-­‐hoc-­‐Anfrage • AP berechnet dynamisch SQL-­‐Anweisung • SQL-­‐Anweisung ist aktueller Parameter von Funk;onsaufrufen an das DBMS è Dynamisches SQL erlaubt Behandlung solcher Fälle § Mehrere Sprachansätze • Eingebe4etes dynamisches SQL • Call-­‐Level-­‐Interface (CLI): kann ODBC-­‐Schni4stelle implemen;eren • Java Database Connec;vity (JDBC) ist eine dynamische SQL-­‐ Schni4stelle zur Verwendung mit Java - JDBC ist gut in Java integriert und ermöglicht einen Zugriff auf rela;onale Datenbanken in einem objektorien;erten Programmiers;l - JDBC ermöglicht das Schreiben von Java-­‐Applets, die von einem Web-­‐ Browser auf eine DB zugreifen können è Funk;onalität ähnlich, jedoch nicht iden;sch Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 21 Dynamisches SQL (2) § Gleiche Anforderungen bei allen Sprachansätzen (LZ) • Zugriff auf Metadaten • Übergabe und Abwicklung dynamisch berechneter SQL-­‐ Anweisungen • Op;onale Trennung von Vorbereitung und Ausführung - einmalige Vorbereitung mit Platzhalter (?) für Parameter - n-­‐malige Ausführung • Explizite Bindung von Platzhaltern (?) an Wirtsvariable - Variable sind zur ÜZ nicht bekannt! - Variablenwert wird zur Ausführungszeit vom Parameter übernommen Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 22 Eingebe4etes dynamisches SQL (EDSQL) § Wann wird diese Schni4stelle gewählt? • Sie unterstützt auch andere Wirtssprachen als C • Sie ist im S;l sta;schem SQL ähnlicher; sie wird oe von Anwendungen gewählt, die dynamische und sta;sche SQL-­‐Anweisungen mischen • Programme mit EDSQL sind kompakter und besser lesbar als solche mit CLI oder JDBC § SQL-­‐Anweisungen werden vom Compiler wie Zeichenke4en behandelt • Deklara;on DECLARE STATEMENT • Anweisungen enthalten Platzhalter für Parameter (?) sta4 Programmvariablen § EDSQL • besteht im wesentlichen aus 4 Anweisungen: - PREPARE: SQL-­‐Anweisung zur (wiederholten) Ausführung vorbereiten - DESCRIBE: Erlaubt Zugriff auf Beschreibungsinforma;on der Anweisung - EXECUTE: Ausführung einer vorbereiteten Anweisung - EXECUTE IMMEDIATE: Entspricht PREPARE + EXECUTE Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 23 Eingebe4etes dynamisches SQL (2) § Beispiel: exec sql begin declare sec;on; char Anweisung [256], X[3]; exec sql end declare sec;on; exec sql declare SQLanw statement; /* Zeichenke4e kann zugewiesen bzw. eingelesen werden */ Anweisung = ‘DELETE FROM Pers WHERE Anr = ?‘; /* Prepare-­‐and-­‐Execute op;miert die mehrfache Verwendung einer dynamisch erzeugten SQL-­‐Anweisung */ exec sql prepare SQLanw from :Anweisung; exec sql execute SQLanw using ‘K51‘; scanf (“ %s ” , X); exec sql execute SQLanw using :X; Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 24 Call-­‐Level-­‐Interface § Schni4stelle ist Sammlung von Prozeduren/Funk;onen • Direkte Aufrufe der Rou;nen einer standardisierten Bibliothek • Keine Vorübersetzung (Behandlung der DB-­‐Anweisungen) - Vorbereitung der DB-­‐Anweisung geschieht erst beim Aufruf zur LZ - Anwendungen brauchen nicht im Quell-­‐Code bereitgestellt werden - Wich;g zur Realisierung von kommerzieller AW-­‐Soeware bzw. Tools è Schni4stelle wird sehr häufig in der Praxis eingesetzt § Einsatz typischerweise in Client/Server-­‐Umgebung Anwendung call return Client CLI-Handler (driver manager) dynamic SQL return DBS_Server Informa;onssysteme 2015 Server Kapitel 9: Anwendungsprogrammierschni4stellen 25 Call-­‐Level-­‐Interface (2) § Vorteile von CLI • Schreiben portabler Anwendungen - keinerlei Referenzen auf systemspezifische Kontrollblöcke wie SQLCA/ SQLDA - kann die ODBC-­‐Schni4stelle implemen;eren • Systemunabhängigkeit - Funk;onsaufrufe zum standardisierten Zugriff auf den DB-­‐Katalog • Mehrfache Verbindungen zur selben DB - unabhängige Freigabe von Transak;onen in jeder Verbindung - nützlich für AW mit GUIs (graphical user interfaces), die mehrere Fenster benutzen • Op;mierung des Zugriffs vom/zum Server - Holen von mehreren Zeilen pro Zugriff - Lokale Bereitstellung einzelner Zeilen (Fetch) - Verschicken von zusammengesetzten SQL-­‐Anweisungen - Client-­‐Programme können Stored Procedures (PSM) aufrufen Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 26 Call-­‐Level-­‐Interface (3) § Wie kooperieren AP und DBMS? • maximale gegensei;ge Kapselung • Zusammenspiel AP/CLI und DBMS ist nicht durch Übersetzungsphase vorbereitet - keine DECLARE SECTION - keine Übergabebereiche AP CLI-Handler • Wahl des DBMS zur Laufzeit • vielfäl;ge LZ-­‐Abs;mmungen DBS DBS erforderlich § Konzept der Handle-­‐Variablen wesentlich • „Handle“ (internes Kennzeichen) ist letztlich eine Programmvariable, die Informa;onen repräsen;ert, die für ein AP durch die CLI-­‐Implemen;erung verwaltet wird • gesta4et Austausch von Verarbeitungsinforma;onen 1 Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 2 27 Call-­‐Level-­‐Interface (4) § 4 Arten von Handles • Umgebungskennung repräsen;ert den globalen Zustand der Applika;on • Verbindungskennung - separate Kennung: n Verbindungen zu einem oder mehreren DBMS - Freigabe/Rücksetzen von Transak;onen - Steuerung von Transak;onseigenschaeen (Isola;onsgrad) • Anweisungskennung - mehrfache Defini;on, auch mehrfache Nutzung - Ausführungszustand einer SQL-­‐Anweisung; sie fasst Informa;onen zusammen, die bei sta;schem SQL in SQLCA, SQLDA und Posi;onsanzeigern (Cursor) stehen • Deskriptorkennung enthält Informa;onen, wie Daten einer SQL-­‐Anweisung zwischen DBMS und CLI-­‐Programm ausgetauscht werden § CLI-­‐Standardisierung in SQL3: • ISO-­‐Standard seit 1996, starke Anlehnung an ODBC bzw. X/Open CLI • Standard-­‐CLI umfasst über 40 Rou;nen: Verbindungskontrolle, Ressourcen-­‐Alloka;on, Ausführung von SQL-­‐Befehlen, Zugriff auf Diagnoseinforma;on, Transak;onsklammerung, Informa;onsanforderung zur Implemen;erung Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 28 Standard-­‐CLI: Beispiel #include “sqlcli.h” #include <string.h> . . . { SQLCHAR * server; SQLCHAR * uid; SQLCHAR * pwd; HENV henv; // environment handle HDBC hdbc; // connec;on handle HSTMT hstmt; // statement handle SQLINTEGER id; SQLCHAR name [51]; /* connect to database */ SQLAllocEnv (&henv); SQLAllocConnect (henv, &hdbc) ; if (SQLConnect (hdbc, server, uid, pwd, ...) != SQL_SUCCESS) return (print_err (hdbc, ...) ) ; /* create a table */ SQLAllocStmt (hdbc, &hstmt) ; { SQLCHAR create [ ] = “CREATE TABLE NameID (ID integer, Name varchar (50) ) ” ; Informa;onssysteme 2015 if (SQLExecDirect (hstmt, create, ...) != SQL_SUCCESS) return (print_err (hdbc, hstmt) ) ; } /* commit transac;on */ SQLTransact (henv, hdbc, SQL_COMMIT); /* insert row */ { SQLCHAR insert [ ] = “INSERT INTO NameID VALUES (?, ?) ” ; if (SQLPrepare (hstmt, insert, ...) != SQL_SUCCESS) return (print_err (hdbc, hstmt) ) ; SQLBindParam (hstmt, 1, ..., id, ...) ; SQLBindParam (hstmt, 2, ..., name, ...) ; id = 500; strcpy (name, “Schmidt”) ; if (SQLExecute (hstmt) != SQL_SUCCESS) return (print_err (hdbc, hstmt) ) ; } /* commit transac;on */ SQLTransact (henv, hdbc, SQL_COMMIT) ; } Kapitel 9: Anwendungsprogrammierschni4stellen 29 Beispiel Microsoe – ODBC-­‐Architektur Anwendungsprogramm SQLExecDirect SQLAllocEnv SQLFetch ODBC Client API Optimierung Datenfluss für Cursor ODBC-Treiber-Manager Kontextverwaltung INGRES-ODBC-Treiber Anpassung Bindung - Syntax - Variablen - Datentypen - Parametern Treiberverwaltung Verwaltung Datenquellen ORACLE-ODBC-Treiber Anpassung Bindung - Syntax - Variablen - Datentypen - Parametern INGRES-Netzwerkanpassung RPCs LU6.2 INGRES-Netzwerkanpassung INGRES Informa;onssysteme 2015 ORACLE-Netzwerkanpassung RPCs LU6.2 ORACLE-Netzwerkanpassung ORACLE Kapitel 9: Anwendungsprogrammierschni4stellen 30 DB-­‐Zugriff via JDBC Informa;onssysteme 2015 DB-spezifisches API JDBC API § Java Database Connec;vity Data Access API (JDBC) • unabhängiges, standardisiertes CLI, basierend auf SQL:1999 • bietet Schni4stelle für den Zugriff auf (objekt-­‐) rela;onale DBMS aus Java-­‐Anwendungen § Allgemeines Problem Verschiedene DB-­‐bezogene APIs sind aufeinander abzubilden ... Java-AW (O)RDBS § Überbrückung/Anpassung durch Treiber-­‐Konzept • setzen JDBC-­‐Aufrufe in die DBMS-­‐spezifischen Aufrufe um • Treiber werden z.B. vom DBMS-­‐Hersteller zur Verfügung gestellt • Treiber-­‐Unterstützung kann auf vier verschiedene Arten erfolgen Kapitel 9: Anwendungsprogrammierschni4stellen 31 JDBC – wich;ge Funk;onalität (1) § Laden des Treiber • kann auf verschiedene Weise erfolgen, z.B. durch explizites Laden mit dem Klassenlader: Class.forName (DriverClassName) § Aurau und Schließen einer Verbindung • Connec;on-­‐Objekt repräsen;ert die Verbindung zum DB-­‐Server • Beim Aurau werden URL der DB, Benutzername und Paßwort als Strings übergeben: Connec;on con = DriverManager.getConnec;on (url, login, pwd); Con.close(); Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 32 JDBC – wich;ge Funk;onalität (2) § Anweisungen • Mit dem Connec;on-­‐Objekt können u.a. Metadaten der DB erfragt und Statement-­‐Objekte zum Absetzen von SQL-­‐Anweisungen erzeugt werden • Statement-­‐Objekt erlaubt das Erzeugen einer SQL-­‐Anweisung zur direkten (einmaligen) Ausführung Statement stmt = con.createStatement(); • PreparedStatement-­‐Objekt erlaubt das Erzeugen und Vorbereiten von (parametrisierten) SQL-­‐Anweisungen zur wiederholten Ausführung PreparedStatement pstmt = con.prepareStatement ( “select * from personal where gehalt >= ?”); • Ausführung einer Anfrageanweisung speichert ihr Ergebnis in ein spezifiziertes ResultSet-­‐Objekt ResultSet res = stmt.executeQuery (“select name from personal”); § Schließen von Statements Stmt.close(); Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 33 JDBC -­‐ Anweisungen § Anweisungen (Statements) • Sie werden in einem Schri4 vorbereitet und ausgeführt • Sie entsprechen dem Typ EXECUTE IMMEDIATE im dynamischen SQL • JDBC-­‐Methode erzeugt jedoch ein Objekt zur Rückgabe von Daten § executeUpdate-­‐Methode wird zur direkten Ausführung von UPDATE-­‐, INSERT-­‐, DELETE-­‐ und DDL-­‐Anweisungen benutzt Statement stat = con.createStatement (); int n = stat.executeUpdate (“update personal set gehalt = gehalt * 1.1 where gehalt < 5000.00”); // n enthält die Anzahl der aktualisierten Zeilen § executeQuery-­‐Methode führt Anfragen aus und liefert Ergebnismenge zurück Statement stat1 = con.createStatement (); ResultSet res1 = stat1.executeQuery ( “select pnr, name, gehalt from personal where gehalt >=” + gehalt); // Cursor-­‐Zugriff und Konver;erung der DBMS-­‐Datentypen in passende Java-­‐Datentypen erforderlich (siehe Cursor-­‐Behandlung) Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 34 JDBC – Prepared-­‐Anweisungen § PreparedStatement-­‐Objekt PreparedStatement pstmt; double gehalt = 5000.00; pstmt = con.prepareStatement (“select * from personal where gehalt >= ?”); • Vor der Ausführung sind dann die aktuellen Parameter einzusetzen mit Methoden wie setDouble, setInt, setString usw. und Indexangabe pstmt.setDouble (1, gehalt); • Neben setXXX () gibt es Methoden getXXX () und updateXXX () für alle Basistypen von Java § Ausführen einer Prepared-­‐Anweisung als Anfrage ResultSet res1 = pstmt.executeQuery (); § Vorbereiten und Ausführung einer Prepared-­‐Anweisung zur DB-­‐ Aktualisierung pstmt = con.prepareStatement (“delete from personal where name = ?”); // set XXX-­‐Methode erlaubt die Zuweisung von aktuellen Werten pstmt.setString (1, “Maier”) int n = pstmt.executeUpdate (); // Methoden für Prepared-­‐Anweisungen haben keine Argumente Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 35 JDBC – Ergebnismengen und Cursor § Select-­‐Anfragen und Ergebnisübergabe • Jede JDBC-­‐Methode, mit der man Anfragen an das DBMS stellen kann, liefert ResultSet-­‐Objekte als Rückgabewert ResultSet res = stmt.executeQuery ( “select pnr, name, gehalt from personal where gehalt >=” +gehalt); • Cursor-­‐Zugriff und Konver;erung der DBMS-­‐Datentypen in passende Java-­‐Datentypen erforderlich • JDBC-­‐Cursor ist durch die Methode next() der Klasse ResultSet implemen;ert getInt (“pnr”) getString (“name”) getDouble (“gehalt”) Cursor next() 123 Maier 6230.00 456 Schulze 5877.00 • Zugriff aus Java-­‐Programm while (res.next() ) { System.out.print (res.getInt (“pnr“) + “\t”); System.out.print (res.getString (“name”) + “\t”); System.out.println (res.getDouble (“gehalt”) ); } Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 36 JDBC – Ergebnismengen und Cursor (2) § JDBC definiert drei Typen von ResultSets è siehe Cursor-­‐Eigenschaeen § ResultSet: forward-­‐only - Default-­‐Cursor vom Typ INSENSITIVE: nur next() § ResultSet: scroll-­‐insensi;ve • Scroll-­‐Opera;onen sind möglich, aber DB-­‐Aktualisierungen verändern ResultSet nach seiner Erstellung nicht § ResultSet: scroll-­‐sensitve • Scroll-­‐Opera;onen sind möglich, wobei ein nicht-­‐INSENSITIVE Cursor benutzt wird • Seman;k der Opera;on, im Standard nicht festgelegt, wird vom DBMS-­‐Hersteller definiert! • Oe wird ODBCs sog. KEYSET_DRIVEN-­‐Seman;k implemen;ert. - Änderungen und Löschungen nachträglich sichtbar, Einfügungen nicht! Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 37 JDBC – Ergebnismengen und Cursor (3) § Aktualisierbare ResultSets Statement s1 = con1.createStatement ( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet res= s1.executeQuery (. . .); . . . res.updateString (“name”, “Müller”); . . . res.updateRow (); • Zeilen können in aktualisierbaren ResultSets geändert und gelöscht werden. • Mit res.insertRow () wird eine Zeile in res und gleichzei;g auch in die DB eingefügt. Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 38 JDBC – Zugriff auf Metadaten § Allgemeine Metadaten • Welche Informa;on benö;gt ein Browser, um seine Arbeit beginnen zu können? • JDBC besitzt eine Klasse DatabaseMetaData, die zum Abfragen von Schema-­‐ und anderer DB-­‐Informa;on herangezogen wird § Informa;onen über ResultSets • JDBC bietet die Klasse ResultSetMetaData ResultSet rs1 = stmt1.executeQuery (“select * from personal”); ResultSetMetaData rsm1 = rs1.getMetaData (); • Es müssen die Spaltenanzahl sowie die einzelnen Spaltennamen und ihre Typen erfragt werden können (z. B. für die erste Spalte) int AnzahlSpalten = rsm1.getColumnCount (); String SpaltenName = rsm1.getColumnName (1); String TypName = rsm1.getColumnTypeName (1); • Ein Wertzugriff kann dann erfolgen durch rs1.getInt (2), wenn rsm1.getColumnTypeName (2) den String “Integer” zurückliefert. Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 39 JDBC – Fehler § Fehlerbehandlung • Spezifika;on der Ausnahmen, die eine Methode werfen kann, bei ihrer Deklara;on (throw excep;on) • Ausführung der Methode in einem try-­‐Block, Ausnahmen werden im catch-­‐Block abgefangen try { . . . Programmcode, der Ausnahmen verursachen kann } catch (SQLExcep;on e) { System.out.println (“Es ist ein Fehler aufgetreten :\n”); System.out.println (“Msg: “ + e.getMessage () ); System.out.println (“SQLState: “ + e.getSQLState () ); System.out.println (“ErrorCode: “ + e.getErrorCode () ); }; Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 40 JDBC – Transak;onen § Transak;onen • Bei Erzeugen eines Connec;on-­‐Objekts (z.B. con1) ist als Default der Modus autocommit eingestellt • Um Transak;onen als Folgen von Anweisungen abwickeln zu können, ist dieser Modus auszuschalten con1.setAutoCommit(false); • Für eine Transak;on können sogen. Konsistenzebenen (isola;on levels) wie TRANSACTION_SERIALIZABLE, TRANSACTION_REPEATABLE_READ usw. eingestellt werden con1.setTransac;onIsola;on (Connec;on.TRANSACTION_SERIALIZABLE); § Beendigung oder Zurücksetzen con1.commit(); con1.rollback(); § Programm kann mit mehreren DBMS verbunden sein • selek;ves Beenden/Zurücksetzen von Transak;onen pro DBMS • kein globales atomares Commit möglich Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 41 DB-­‐Zugriff via JDBC – Beispiel 1 import java.sql.*; public class Select { public static void main (String [ ] args) { Connection con = null; PreparedStatement pstmt; ResultSet res; double gehalt = 5000.00; try { Class.forName (“sun.jdbc.odbc.JdbcOdbcDriver”); con = java.sql.DriverManager.getConnection (“jdbc:odbc:personal”, “user”, “passwd”); pstmt = con.prepareStatement (“select pnr, name, gehalt from personal where gehalt >= ?”); pstmt.setDouble (1, gehalt); ... res = pstmt.executeQuery (); while (res.next () ) { System.out.print (res.getInt (“pnr”) + “\t”); System.out.print (res.getString (“name”) + “\t”); System.out.printIn (res.getDouble (“gehalt”) ); } res.close (); pstmt.close (); } / / try catch (SQLException e) { System.out.printIn (e); System.out.printIn (e.getSQLState () ); System.out.printIn (e.getErrorCode () ); } catch (ClassNotFoundException e) { System.out.printIn (e); } } / / main } / / class Select Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 42 DB-­‐Zugriff via JDBC – Beispiel 2 import java.sql.*; public class Insert { public static void main (String [ ] args) { Connection con = null; PreparedStatement pstmt; try { Class.forName (“sun.jdbc.odbc.JdbcOdbcDriver”); con = java.sql.DriverManager.getConnection (“jdbc.odbc.personal”, “ ”, “ ”); pstmt = con.prepareStatement (“insert into personal values (?, ?, ?)”); pstmt.setInt (1, 222); pstmt.setString (2, “Schmitt”); pstmt.setDouble (3, 6000.00); pstmt.executeUpdate (); pstmt.close (); con.close (); } / / try catch (SQLException e) { System.out.printIn (e); System.out.printIn (e.getSQLState () ); System.out.printIn (e.getErrorCode () ); } catch (ClassNotFoundException e) {System.out.printIn (e); } } } ... pstmt = con.prepareStatement (“update personal set gehalt = gehalt * 1.1 where gehalt < ?”); pstmt.setDouble (1, 10000.00); pstmt.executeUpdate (); pstmt.close (); ... pstmt = con.prepareStatement (“delete from personal where pnr = ?”); pstmt.setInt (1,222); pstmt.executeUpdate (); pstmt.close (); Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 43 Anmerkung: SQL Injec;ons § Beispiel • SQL Anfrage wird in Anwendung erstellt, wobei id eine Benutzereingabe ist …. "SELECT author, subject, text" + "FROM ar;kel WHERE ID=' " + id + " ' " • Aufruf z.B. durch Webserver h4p://webserver/cgi-­‐bin/find.cgi?ID=42 § SQL Injec;on zum Ausspähen von Daten h4p://webserver/cgi-­‐bin/find.cgi?ID=42+'+UNION+SELECT+ login,+password,+'x'+FROM+user+WHERE+'x'='x • Führt zur SQL Anweisung: select author, subject, text from ar;kel where ID='42' union select login, password, 'x' from user where 'x'='x'; • Und andere Fälle bis hin zum Einschleusen von beliebigem Code auf Rechner + Öffnen einer Shell (abh. von DBMS) § Hilfe u.a. durch Benutzen von PreparedStatements mit Parametern! • Übersicht unter: h4p://de.wikipedia.org/wiki/SQL-­‐Injec;on Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 44 SQLJ – Eingebe4etes SQL in Java § SQLJ (offiziell: SQL/OLB – Object Language Bindings) • beschreibt die Einbe4ung von SQL in Java-­‐Anwendungen • besitzt bessere Lesbarkeit, Verständlichkeit und Wartbarkeit durch kurze und prägnante Schreibweise • zielt auf die Laufzeiteffizienz von eingebe4etem SQL ab, ohne die Vorteile des DB-­‐Zugriffs via JDBC aufzugeben § SQLJ und JDBC • Ebenso wie sta;sche und dynamische SQL-­‐Anweisungen in einem Programm benutzt werden können, können SQLJ-­‐ Anweisungen und JDBC-­‐Aufrufe im selben Java-­‐Programm auereten. § Im Folgenden werden nur einige Unterschiede zu eingebe4etem SQL und JDBC aufgezeigt Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 45 SQLJ Connec;onContext § Verbindung zum DBMS • erfolgt über sog. Verbindungskontexte (Connec;onContext) • Sie basieren auf JDBC-­‐Verbindungen und werden auch so genutzt (URL, Nutzername, Paßwort) • SQLJ-­‐Programm kann mehrere Verbindungskontexte über verschiedene JDBC-­‐Treiber aurauen; sie erlauben den parallelen Zugriff auf mehrere DBMS oder aus mehreren Threads/Prozessen auf das gleiche DBMS Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 46 SQLJ -­‐ Abbildung auf JDBC durch Precompiler § Abbildung auf JDBC durch Precompiler • Überprüfung der Syntax sowie (gewisser Aspekte) der Seman;k von SQL-­‐ Anweisungen (Anzahl und Typen von Argumenten usw.) zur Übersetzungszeit, was Kommunika;on mit dem DBMS zur Laufzeit erspart • Ersetzung der SQLJ-­‐Anweisungen durch Aufrufe an das SQLJ-­‐Laufzeitmodul (Package sqlj.run;me.*) • Erzeugung sog. Profiles, serialisierbare Java-­‐Klassen, welche die eigentlichen JDBC-­‐Anweisungen enthalten • Abwicklung von DB-­‐Anweisungen vom SQLJ-­‐Laufzeitmodul dynamisch über die Profiles, die wiederum über einen JDBC-­‐Treiber auf die DB zugreifen • Anpassung an ein anderes DBMS geschieht durch Austausch der Profiles (sog. Customizing) *.sqlj SQLJ-Precompiler Syntaxprüfung Erweiterter Java-Quellcode Persistenzfähige Class-Dateien *.java javac *.class Semantik prüfung *.ser DB-Schema Informa;onssysteme 2015 Profiles Kapitel 9: Anwendungsprogrammierschni4stellen 47 SQLJ – Anweisungen und Iteratoren § SQL-­‐Anweisungen sind im Java-­‐Programm Teil einer SQLJ-­‐Klausel #SQL { select p.onr into :persnr from personal p where p.beruf = :beruf and p.gehalt > :gehalt}; • Austausch von Daten zwischen SQLJ und Java-­‐Programm erfolgt über Wirtssprachenvariablen • Parameterübergabe kann vorbereitet werden • ist viel effizienter als bei JDBC (mit ?-­‐Platzhaltern) § Iteratoren • analog zu JDBC-­‐ResultSets • Defini;on von Iteratoren (Cursor), aus denen entsprechende Java-­‐Klassen generiert werden, über die auf die Ergebnismenge zugegriffen wird Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 48 SQLJ NamedIterators § Nutzung eines Iterators in SQLJ import java.sql.* . . . #SQL iterator GetPersIter (int personalnr, String nachname); Get PersIter iter1; #SQL iter1 = {select p.pnr as “personalnr”, p.name as “nachname” from personal p where p.beruf = :Beruf and p.gehalt = :Gehalt}; int Id; String Name; while (iter1.next ()) { Id = iter1.personalnr (); Name = iter1.nachname (); … Verarbeitung … } iter1.close (); § SQLJ liefert für eine Anfrage ein SQLJ-­‐Iterator-­‐Objekt zurück • SQLJ-­‐Precompiler generiert Java-­‐Anweisungen, die eine Klasse GetPersIter definieren • Deklara;on gibt den Spalten Java-­‐Namen (personalnr u. nachname) und definiert implizit Zugriffsmethoden personalnr() u. nachname(), die zum Iterator-­‐Zugriff benutzt werden Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 49 Zusammenfassung § Cursor-­‐Konzept zur satzweisen Verarbeitung von Datenmengen • Anpassung von mengenorien;erter Bereitstellung und satzweiser Verarbeitung von DBMS-­‐Ergebnissen • Opera;onen: DECLARE CURSOR, OPEN, FETCH, CLOSE • Erweiterungen: Scroll-­‐Cursor, Sichtbarkeit von Änderungen § Sta;sches (eingebe4etes) SQL • hohe Effizienz, gesamte Typprüfung und Konver;erung erfolgen durch Precompiler • rela;v einfache Programmierung • Aurau aller SQL-­‐Befehle muss zur Übersetzungszeit festliegen • es können zur Laufzeit nicht verschiedene Datenbanken dynamisch angesprochen werden § Übersetzung, Code-­‐Erzeugung und Ausführung einer DB-­‐Anweisung • für jede DB-­‐Anweisung wird ein zugeschni4enes Programm erzeugt (Übersetzungszeit), das zur Laufzeit abgewickelt wird und dabei mit Hilfe von Aufrufen des Zugriffssystems das Ergebnis ableitet • Übersetzungsaufwand wird zur Laufzeit soweit wie möglich vermieden Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 50 Zusammenfassung (2) § Interpreta;on einer DB-­‐Anweisung • allgemeines Programm (Interpreter) akzep;ert Anweisungen der DB-­‐Sprache als Eingabe und erzeugt mit Hilfe von Aufrufen des Zugriffssystems Ergebnis • hoher Aufwand zur Laufzeit (v.a. bei wiederholter Ausführung einer Anweisung) § Dynamisches SQL • Festlegung/Übergabe von SQL-­‐Anweisungen zur Laufzeit • hohe Flexibilität, schwierige Programmierung § Unterschiede in der SQL-­‐Programmierung zu eingebe4etem SQL • explizite Anweisungen zur Datenabbildung zwischen DBMS und Programmvariablen • klare Trennung zwischen Anwendungsprogramm und SQL (einfacheres Debugging) Informa;onssysteme 2015 Kapitel 9: Anwendungsprogrammierschni4stellen 51