8. SQL zur Anwendungsprogrammierung (embedded SQL, ESQL) 8.1 Einführung 8.2 Vorübersetzung 8.3 Cursor-Konzept 8.4 Programmstruktur und Variablen 8.5 Deklarative EXEC SQL-Anweisungen 8.6 Ausführbare EXEC SQL-Anweisungen 8.7 „Dynamisches“ ESQL 8.8 Abschließendes zum Thema „Anwendungsprogrammierung“ Datenbanksysteme 2 46 8.1 Einführung • Bisher betrachtet bzw. implizit vorausgesetzt: - Eingabe von SQL-Anweisungen aller Art am Bildschirm - Ausgabe von Ergebnissen (Tupelmengen, Fehlermeldungen etc.) ebenfalls am Bildschirm „interaktives SQL“, Ad-hoc-Anfragen (ISQL) keine unmittelbare Weiterverarbeitung von Anfrageergebnissen durch Anwendungsprogramme; auch z.B. keine Datenänderungen / Einfügungen / ... durch Anwendungsprogramme für die Praxis eigentlich wichtigere Fall (Szenarium) als Ad-hoc-Anfragen!! Einbettung von SQL in Anwendungsprogramme, die in einer (meist) höheren Programmiersprache geschrieben wird: Java, C++, C, COBOL, PROLOG, Ada etc. etc. • Merke: „In der Praxis existiert der Mensch, der mit SQL interaktiv am Bildschirm arbeitet (zumindest unter den DB-Anwendern), fast nicht.“ Datenbanksysteme 2 47 (hatten sich die SQL-Väter so eigentlich nicht vorgestellt ... SEQUEL = Structured English Query Language) Probleme/Aufgabenstellungen bei Einbettung von SQL in Anwendungsprogramme • Programmiersprache einerseits und SQL andererseits sind „verschiedene Sprachen“ (offensichtlich) Wie „kommt´s zusammen“, wie schreibt man bzw. was geschieht mit ein/em Programm, das beiderlei Sprachelemente enthält? • Mengenorientierung in SQL auf der einen Seite (plus deskriptiv) vs. prozedurale, satzorientierte Programmiersprache (impedance mismatch) wie „zu verheiraten“? [U.a.: SQL-Anfragen können „beliebig große“, vorher bzgl. der Kardinalität nicht unbedingt vorhersehbare Anfrageergebnisse liefern] • Zusammenbringen u.a. von unterschiedlichen Datentypen, Attributlängen (2 GB-Attributwerte ...) etc. in SQL & Programmiersprache Datenbanksysteme 2 48 Datenbankzugriff aus Anwendungsprogrammen Thema: Bereitstellung von Möglichkeiten zur persistenten Datenhaltung / des DBMS-Anschlusses für Anwendungsprogramme Grundsätzliche Möglichkeiten: Wie kommt mein AP an die relational gespeicherten Daten heran? Zusammenbringen der rel. DB-Sprache SQL einerseits und der Programmiersprache andererseits 1. Pre-compiler Ansatz (Vorübersetzung): Programm enthält (markierte) DB-Anweisungen und wird zunächst vorübersetzt vor eigentlicher Programmübersetzung Pre-compiler erzeugt Programm-Quellcode-Abschnitte (u.a.) Details gleich 2. DBMS-Aufrufe quasi als Unterprogramm aus AP heraus (Call Level Interface, CLI). Kein Pre-compiler erforderlich, keine Programmierspracherweiterung Bekannte CLI-Schnittstellen (Industrie-Standards): ODBC (Open Database Connectivity), MS etc. JDBC (Java … Datenbankanschluss), Sun etc. Datenbanksysteme 2 49 3. (Einfache) Programmierspracherweiterungen zur Anbindung von Datenbankanweisungen: Erweiterung der Programmiersprachensyntax und –semantik Bsp.: Einbindung der CODASYL-Datenbanksprache in Programmiersprache Konsequenz: Erweiterter Programmiersprachencompiler !! Wichtig: Kein Erweitertes Typsystem in Programmiersprache 4. (Komplexe) Programmierspracherweiterungen zur engen Einbindung von Datenbankanweisungen Erweiterung der Programmiersprachensyntax und –semantik (beträchtlicher Art!) !! Wichtig: Erweitertes Typsystem in Programmiersprache, z.B. „Relation as a Data Type“, Programmschleifen über Tabelleninhalte relationale Objekte wie normale Programmiersprachenobjekte behandelbar integrierter Ansatz Bsp.: Pascal/R, Modula/R, DBPL (Data Base Programming Language) Schmidt/Uni Hamburg, TU HH leider keine praktische Verbreitung erlangt, nur Forschung-/ Prototypstatus (weil aufwendige Programmierspracherweiterung erforderlich, quasi „neue Sprache“ den Datenbanken zuliebe) Datenbanksysteme 2 50 5. Sog. 4GL- Sprachen (4th Generation Language) Bsp.: ABAP (SAP, Advanced Business Application Programming) NATURAL (Software AG) Proprietäre Sprachentwicklungen einer „neuen“ höheren Programmiersprache unter Einbeziehung von integriertem Datenbankzugriff und –verarbeitung. Beispiele auf Kopien (werden ausgeteilt) 5 Varianten unterscheiden sich deutlich vor allem in bezug auf Integrationsgrad zwischen Programmiersprache und DB-Sprache: Sehr hohe (enge) Integration insbesondere bei 4 und 5, sehr geringe (lose) Integration insbesondere bei 2. Enge Bindung zwischen Programmiersprache und DB-Sprache hat Einfluss auf Benutzbarkeit, Performance, Erweiterbarkeit (der Sprache) Datenbanksysteme 2 51 8.2 Vorübersetzung • Gewählter und ein in der Praxis wichtiger Ansatz: Vorübersetzung von Programmen mit eingebetteten SQLAnweisungen ( Präprozessor, Pre-compiler, Vorübersetzer): Quell-Code Anwendungsprogramm mit SQL-Anweisungen Pre-compiler Quell-Code Anwendungsprogramm ohne SQL-Anweisungen Normaler Programmiersprachenübersetzer ausführbares Programm (Objekt-Code) • Bemerkungen zum Ansatz der Vorübersetzung: - Pre-compiler muss zwar Teile der jeweiligen Wirtsprogrammsyntax (C, etc. ...) ebenfalls verstehen, aber weitgehende Entkopplung Datenbanksysteme 2 52 angestrebt: Pre-compiler kann vergleichsweise klein/einfach gehalten werden, unabhängige Weiterentwicklung (Portabilität), keine „Doppelübersetzung“ eines Programms - Pre-compiler sucht nach / analysiert lediglich markierte/n Teile/n im Anwendungsprogramm: Präfix EXEC SQL [...]: Alles Teil diese Teile werden entfernt bzw. durch Anweisungen der jeweiligen der SQL-Norm Wirtsprogrammsyntax ersetzt (u.a. durch Prozedur/Unterprogrammaufrufe) - Pre-compiler führt (zumindest) syntaktische Prüfungen durch – und meldet etwaige Fehler auf mehreren „Ebenen“: • Fehler in den eingebetteten markierten (und analysierten) Programmteilen: „lokal“ prüfbar • Fehler in den eingebetteten SQL-Anweisungen*: SQLAnweisungen werden nicht vom Pre-compiler selbst „lokal“ analysiert und geprüft, sondern hierzu aus DatenbankVerwaltungssystem (DBVS, Server) übergeben DBVS besitzt ohnehin SQL-Übersetzer, dieser braucht nicht zusätzlich im Precompiler (Client) vorhanden sein * Prüfungen nur bei sog. „statischem SQL“ möglich, s.u. Datenbanksysteme 2 53 falls Fehler bereits bei Vorübersetzung entdeckt werden, kann man sich sinnlose Quellprogrammübersetzung sparen (und erst recht manche Runtime-Fehler!) ... - Quellprogrammcode-Erzeugung durch den Pre-compiler für: • Hilfsvariablen (Kontrollblöcke) für SQL(DBVS)–Statusinformation und Parameterübergabe Anwendungsprogramm SQLLaufzeitsystem • Unterprogrammaufrufe an das SQL-Laufzeitsystem ( Bild, Tafel!) für - Verbindungsaufbau/-abbau mit DBVS - Absetzen von SQL-Anweisungen aller Art - Verarbeitung von Anfrageergebnismengen (Cursor s.u.) • Behandlung von Fehlern und Endebedingungen („exception handling“) Datenbanksysteme 2 54 8.3 Cursor-Konzept („heilt“ Impedance Mismatch, mehr oder weniger ...) • Aufgabe: Verarbeitung von Tupelmengen im Anwendungsprogramm (u.a. Lesen/Abarbeiten von SQL-Anfrageergebnissen (SELECT...)) „Brücke“ zwischen mengenorientierter Datenbanksprache und prozeduraler, satzorientierter Programmiersprache • ... weil: Beliebig(& unvorhersehbar) große Tupelmengen können nicht einfach „als ganzes“ zwischen DBVS und Anwendungsprogramm ausgetauscht werden: - Einige/viele Programmiersprachen kennen keine „dynamischen Arrays“ - Selbst wenn: Speicherplatzfrage, „Kosten“ für Allokation/Deallokation großer Speicherbereiche im (virtuellen) Speicher - Umgehen mit sehr langen Attributwerten (LOBs) - Anwendungsprogramm will u.a. gar nicht alles lesen, sondern ggf. abbrechen - etc. Datenbanksysteme 2 55 OPEN CURSOR • Datenbank-Cursor: Spezielle Laufvariable zum satzweisen Abarbeiten der Ergebnismenge einer eingebetteten SQL-SELECTAnweisung • Cursor-Definition im Anwendungsprogramm legt Bindung an SQLSELECT-Anweisung fest • Cursor steht nach dem Ausführen der zugehörigen SQL-SELECTAnweisung vor dem ersten Tupel der Ergebnismenge, die auch leer sein darf • Anschließende Cursor-Operationen (FETCH, s.u.) bewegen Cursor mit Schrittweite 1 über die Ergebnismenge hinweg und übertragen jeweils 1 Tupel ins Anwendungsprogramm 1 Ergebnismenge 1 1 2 3 4 5 6 7 8 FETCH FETCH FETCH FETCH FETCH FETCH FETCH FETCH ... ... = Initialzustand des Cursors nach Ausführen der SQL-SELECT-Anweisung (OPEN CURSOR) • Wichtiger Sonderfall: Liefert eine SQL-SELECT-Anweisung max. 1 Tupel zurück, kann auf Cursor verzichtet werden Datenbanksysteme 2 56 8.4 Programmstruktur und Variablen Einfaches Beispielprogramm (schematisch) 1 2 3 4 # include-Teil < Deklaration nur im Anwendungsprog. verwendeter Variablen > EXEC SQL BEGIN DECLARE SECTION; < Deklaration ´gemeinsam´ (AP, ´SQL´) verwendeter Variablen > Host-Var.! EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; /* SQL Communication Area */ main() { EXEC SQL WHENEVER SQLERROR GOTO sqlfehler; EXEC SQL DECLARE cursor1 CURSOR FOR SELECT . . . FROM . . . WHERE . . . ; EXEC SQL OPEN cursor1; /* SQL-Anweisung ausführen */ while (SQLCA.SQLCODE == 0) { EXEC SQL FETCH cursor1 INTO : variable1, : variable2 ...; Host-Var.! < Verarbeitung des gelesenen Tupels > } EXEC SQL CLOSE cursor1; EXEC SQL COMMIT WORK; exit (0); sqlfehler: /* Fehlerbehandlung */ < Ausgabe Fehlermeldung > exit (1); } Datenbanksysteme 2 57 Bemerkungen/Erklärungen zum Beispielprogramm 1 2 3 4 Gemeinsam verwendete Variablen: Programmvariablen, die in FETCHAnweisungen oder ESQL-Anweisungen als Host-Variablen vorkommen: • bei FETCH: siehe Beispiel oben • bei ESQL: SELECT aname FROM angest WHERE anr = : variable3; gewisse Flexibilität auch bei „statischem“ ESQL Für Fehlermeldungen, Warnungen etc. Bindung zwischen Cursor und SQL-SELECT-Anweisung; [Pre-compiler „entnimmt“ hier SQL-Anweisung und übergibt sie zum Übersetzen/Prüfen dem DBMS (zum Vorübersetzungszeitpunkt des AP)] OPEN veranlasst „Ausführung“ der SQL-SELECT-Anweisung (mit ggf. aktuellen Host-Variablen-Belegungen à la variable3 oben) und Positionieren des Cursors vor erstes Ergebnistupel, FETCH schiebt Cursor um eine Position weiter und überträgt Tupel ins AP, CLOSE schließt Cursor Datenbanksysteme 2 58 8.5 Deklarative EXEC SQL-Anweisungen* (* EXEC SQL ... Anweisungen Pre-compiler) BEGIN a) EXEC SQL END DECLARE SECTION Host-Var. Deklaration ´gemeinsam´ verwendeter Variablen, wie besprochen b) EXEC SQL INCLUDE SQLCA; SQL Communication Area (Fehlermeldungen ...), wie besprochen c) EXEC SQL INCLUDE SQLDA; SQL Descriptor Area (für die Ausführung von „dynamischem“ SQL, d.h. wenn SQL-Anweisung zur Übersetzungszeit des Programms noch nicht bekannt ist, sondern erst zur Ausführungszeit, siehe 8.7) d) EXEC SQL WHENEVER SQLERROR SQLWARNING NOT FOUND CONTINUE ; GOTO stmt-label Beispiele: EXEC SQL WHENEVER NOT FOUND GOTO ende; EXEC SQL WHENEVER SQLERROR GOTO sqlfehler; EXEC SQL WHENEVER SQLWARNING CONTINUE; Datenbanksysteme 2 59 ermöglicht „zentrales“ exeption handling, d.h. vor allem, nicht nach jedem Statement (OPEN, FETCH ...) müssen mühsam die Return Codes abgefragt werden den Programm-Code für diese einzelnen Abfragen erzeugt vielmehr der Precompiler Realisierung: • Die vom Pre-compiler generierten Abfragen beziehen sich auf sqlcode und sqlwarn innerhalb von sqlca (SQL Communication Area): - SQLERROR sqlcode < 0 - NOT FOUND sqlcode = 100 (keine Datensätze (mehr) gefunden) - SQLWARNING: Testet Inhalt von sqlwarn • EXEC SQL WHENEVER kann wiederholt im Programm vorkommen: Eine WHENEVER-Anweisung gilt, bis sie durch eine andere WHENEVER-Anweisung mit gleichem Bedingungsteil ersetzt wird. e) EXEC SQL DECLARE cursorname FOR <query>; wie besprochen; falls bekannt ist, dass max. 1 Ergebnistupel existiert, kann statt Cursor SELECT ... INTO ... benutzt werden: Bsp.: Vorteil? Nachteil? Datenbanksysteme 2 EXEC SQL SELECT aname INTO :variable1 FROM angest WHERE anr =:variable2; Klappt wg. Schlüsseleigenschaft von anr 60 8.6 Ausführbare EXEC SQL-Anweisungen* - Interaktion mit DB-Server – (* EXEC SQL ... Anweisungen Pre-compiler) a) EXEC SQL CONNECT . . .; Verbindungsaufbau AP DBVS und Identifikation des Benutzers / Autorisierungsprüfung; nicht bei allen Datenbanksystemen in dieser Form vorhanden OPEN b) EXEC SQL CLOSE cursorname; wie besprochen; ein Cursor kann in einem Programm, wenn nötig, mehrfach geöffnet/geschlossen werden (wozu?), vor erneutem Öffnen muss aber jeweils Schließen erfolgen c) EXEC SQL FETCH cursorname INTO :hostvar1, ..., :hostvarn; wie besprochen; Cursor wird um eine Position weiter geschoben, und anschließend erfolgt Transfer des Tupel in die angegebenen Host-Variablen Nur „Vorwärtsschieben“ um jeweils 1 Position möglich, SQL92ff erlauben jedoch mehr („scrollable cursors“) Freies Cursor-Positionieren Datenbanksysteme 2 61 Einschub: Bemerkungen zur Interaktion zwischen AP und DBVS insb. bei Client-Server-Verarbeitung • Sehr „einfaches“ Vorgehensmodell wäre: OPEN CURSOR ( QueryAusführung) überträgt gesamtes Anfrageergebnis zum AP, das dann mit Cursor-Operation lokal darauf arbeitet i.d.R. zu teuer, unerwünscht (aber: Vorteile?) • Real existierendes Vorgehensmodell: OPEN CURSOR (Anfrage“Ausführung“) materialisiert Anfrageergebnis zunächst nicht unbedingt, sondern setzt auch auf DBVS-Seite – ähnlich wie auf APSeite – nur „Positionszeiger“ Scans, entsprechen Cursors Erst bei nachfolgenden FETCH-Operationen werden die benötigten Daten aus der DB gelesen und zum AP übertragen: Einfach, solange nur Vorwärtsschieben um 1, komplizierter (für das DBVS und das SQLLaufzeitsystem) bei „scrollable cursors“ Datenbanksysteme 2 62 d) EXEC SQL SELECT attributliste INTO hostvariablenliste FROM ... [WHERE ...]; wie bereits kurz angesprochen; nur bei Anfragen mit max. 1 Treffer, sonst Laufzeitfehlermeldung nur für (allerdings wichtige) „Spezialfälle“ INSERTe) EXEC SQL UPDATE- Anweisung DELETE- ; 1) Zur Einbettung von INSERT/UPDATE/DELETE-Anweisungen ins AP, werden DBVS-seitig ausgeführt („durchgeschoben“) 2) Spezielle Form: Positioniertes Update/Delete mit Bezugnahme auf Cursor-Position EXEC SQL UPDATE relationsname SET ... z.B. für updatable views WHERE CURRENT OF cursorname; EXEC SQL DELETE FROM relationsname WHERE CURRENT OF cursorname; Cursor muss offen sein und in „ON-Position“ (steht bei DELETE danach vor nächstem Ergebnistupel) Datenbanksysteme 2 63 f) EXEC SQL CREATE DROP ALTER TABLE < Anweisung >; wie bei interaktivem SQL g) EXEC SQL CREATE DROP INDEX < Anweisung >; wie bei interaktivem SQL f & g innerhalb von Anwendungsprogrammen eher selten anzutreffen, jedoch z.B. in Datenbankreorganisationsprogrammen o.ä. ( Datenbankadministration) h) EXEC SQL COMMIT ROLLBACK [WORK] Die aktuelle Verarbeitungseinheit (Transaktion Folge zusammengehöriger Datenbankanweisungen) wird abgeschlossen; die durchgeführten Änderungen aller Art werden in der Datenbank ´permanent gemacht´ (COMMIT) bzw. – etwa im Fehlerfall - ´ausgelöscht´ (ROLLBACK). Bei ROLLBACK sind anschließend keine ´Spuren´ der Transaktion mehr in der Datenbank anzutreffen. Datenbanksysteme 2 64 8.7 „Dynamisches“ ESQL a) Einführung/Motivation • Bisher betrachtet: „Statisches“ ESQL, SQL-Anweisungen im Programm zum (Vor-)Übersetzungszeitpunkt bekannt (bis auf Werte von Host-Variablen), Struktur der Ergebnisrelation (bei SQL-SELECTAnweisung) ebenfalls bekannt! Vorteile: - Umfangreiche Prüfungen möglich zum (Vor-)Übersetzungszeitpunkt - Übesetzung/Optimierung/... für SQL-Anweisung einmal zur (Vor-)Übersetzungszeit, keine Aufwendungen hierfür zur Programmausführungszeit - Recht einfache Handhabung (s.o.) Nachteile: - U.U. inflexibel, keine ´generischen´Aufwendungsprogramme möglich (à la ´Relationeneditor´, QbE-artige Schnittstelle o.ä.) für jeden Spezialfall zugeschnittenes Anwendungsprogramm erforderlich ( teils undurchführbar) Datenbanksysteme 2 65 - Auch Cusor-Namen und –Anzahl im Programm fest „verdrahtet“, d.h. auch hier keine Flexibilität Lösung „Dynamisches“ ESQL • SQL-Anweisungen müssen erst zur Laufzeit des Programms bekannt sein, d.h. können bei Bedarf in Zeichenkettenvariablen „zusammengebaut“ werden, vom Bildschirm eingelesen werden o. dgl. • Ergebnisstruktur bei SELECT-Anweisungen muss ebenso erst zur Laufzeit vorliegen, wird dann vom Anwendungsprogramm dynamisch interpretiert • Cursor können ggf. zur Laufzeit dynamisch erzeugt werden, d.h. keine „Verdrahtung“ zum Zeitpunkt der Programmerstellung nötig Datenbanksysteme 2 66 b) Zwischenstufen auf dem Weg zum „voll dynamischen“ ESQL 0. Host-Variablen in ansonsten statischen ESQL-Anweisungen, wie oben beschrieben („parametrische Queries“): SELECT aname FROM angest Festlegung der Struktur der Ergebnisrelation zum Programmierungszeitpunkt WHERE anr = :variable; nur sehr geringe Flexibilität 1. Aufbau kompletter SQL-Anweisung als Zeichenkette und Übergabe ans DBVS zur Ausführung: ausführbare Anweisung strcpy (strg, "INSERT INTO angest VALUES (´4711´, ´Müller´)"); EXEC SQL EXECUTE IMMEDIATE strg; geht nicht für SELECT-Anweisungen (da kein Cursor involviert), keine Übergabe eines Anfrageergebnisses möglich 2. „Voll dynamisches“ ESQL unter Verwendung der SQLDA (SQL Descriptor Area, siehe auch bereits kurz in 8.5) Was ist die SQLDA ? Datenbanksysteme 2 67 deklarative Anweisung • Vordefinierter Datenstrukturtyp, der über EXEC SQL INCLUDE SQLDA; vom Pre-compiler ins Anwendungsprogramm eingefügt wird (à la SQLCA) • Der jeweiligen Host-Sprache gemäß (struct in C; bei anderen Programmiersprachen entsprechender Konstruct) • Hier werden vom SQL-Laufzeitsystem zur Programmausführungszeit die Informationen ans AP übergeben über (bei ESQL SELECT): ! - Struktur der Ergebnisrelation (Spaltenanzahl, Attributnamen, typen, -längen) Relationenschema - Verweise (Pointer) auf die Attributwerte eines aktuellen Ergebnistupels + Längenangaben + Nullwertindikator SQLDA-Information ermöglicht dem AP die Interpretation des Anfrageergebnisses (Ergebnisrelation) sowohl bzgl. der Ergebnisstruktur als auch bzgl. der aktuell übergebenen Werte (Ergebnistupel) mehr Details siehe Karl-Neumann-Buch!! Datenbanksysteme 2 68 c) Vorgehensweise (skizziert) zur Verwendung von (voll) dynamischem ESQL in einem AP 1. Deklaration der SQLDA im AP EXEC SQL INCLUDE SQLDA; (nur Datenstrukturtyp, keine Variable!) 2. 3. Vereinbarung eines Zeigers auf den SQLDA-Bereich: struct sqlda *daptr; Zuweisung einer SQL-Anweisung (als Zeichenkette) an eine HostVariable + Übersetzung der SQL-Anweisung (Struktur der Ergebnisrelation anschließend bekannt*!): (* aber noch nicht ans AP übergeben ausführbare Anweisung 4. strcpy (strg, "SELECT ..."); EXEC SQL PREPARE s1 FROM :strg; Deklaration eines Cursors für die SQL-Anweisung/Ergebnisrelation: EXEC SQL DECLARE curs1 CURSOR FOR s1; 5. Allokation von Speicherplatz für den SQLDA-Bereich (refernziert über daptr) Datenbanksysteme 2 69 „Füllen“ des über daptr referenzierten SQLDA-Bereichs mit Strukturinformationen zur Ergebnisrelation (Spaltenzahl, Attributnamen, -typen, -länge ...): ausführEXEC SQL DESCRIBE s1 INTO: daptr; bare Anweisung Das AP kennt jetzt die Struktur des Anfrageergebnisses und kann sich darauf „einrichten“ (z.B. Bildschirmausgabemasken erzeugen o.ä.) 7. Cursor öffnen und SQL-Anweisung ausführen (im Grunde wie bei statischem ESQL): EXEC SQL OPEN curs1 USING DESCRIPTOR :daptr; 8. Schrittweises Lesen der Ergebnistupel: (wie bei statischem ESQL) EXEC SQL FETCH curs1 USING DESCRIPTOR :daptr; 9. Schließen des Cursors (wie bei ...): EXEC SQL CLOSE curs1; 6. ! Datenbanksysteme 2 70 Bemerkungen zum dynamischen ESQL • In der Handhabung aufwändiger/umständlicher/„teurer“ als statisches ESQL (der Preis, den man für die größere Flexibilität zahlen muss) • Trennung in viele „Einzelschritte“ erhöht Flexibilität weiter bzw. hat auch Performance-Vorteile (z.B. PREPARE nur einmal und dann wiederholtes OPEN FETCH*/CLOSE ohne Neuübersetzung der SQLAnweisung oder auch mehrere Cursor auf einem „Ergebnisrelationstyp“) • Es gibt noch weitere Varianten/Optionen bei dynamischem ESQL, die wie hier nicht näher betrachten wollen Datenbanksysteme 2 71 Grundsätzliches zum dynamischen ESQL • Dynamisches ESQL ist natürlich, was die Ausführungszeit/Ressourcenverbrauch anbelangt, teurer als statisches ESQL Übersetzung der ESQL-Anweisung (mit Optimierung, Codegenerierung ...) findet erst zur AP-Laufzeit statt, nicht schon zur Übersetzungszeit • Meinung mancher Benutzer/DB-Administratoren: „Dynamisches ESQL considered harmful“? • Wie weit dynamisches ESQL den Ressourcenverbrauch prozentual hochtreibt gegenüber statischem ESQL, hängt von SQL-StatementEigenschaften ab (Größe der Ergebnisrelation, allg. Ausführungskosten) Übersetzung der SQL-Anweisung zur APLaufzeit bedeutet „Grund-Overhead“, der prozentual um so stärker ins Gewicht fällt, je billiger die eigentliche Statement-Ausführung ist dynamisches ESQL kann Anwendung deutlich verlangsamen (ob tolerierbar, kann nur im konkreten Fall entschieden werden) • Dynamisches ESQL nicht planlos/“kopflos“ einsetzen!! Datenbanksysteme 2 72 • Eine (Teil-)Lösung: SQL-Statement-Cache vom DBVS verwaltet ( à la Oracle): - „Präparierte“ ESQL-Anweisungen (PREPARE ...) werden vom DBVS in einem SQL-Statement-Cache aufgehoben (AP merkt hiervon nichts) - Bei jedem PREPARE wird vom DBVS „unter der Decke“ nachgeschaut, ob Anweisung evtl. bereits „präpariert“ wurde und noch als solche im Cache vorhanden ist Neuübersetzung kann dann unterbleiben - Lohnt sich vor allem bei Anwendungen, die sehr stark auf dyn. ESQL basieren (z.B. SAP R/3!!) - Gar nicht so trivial: • Wie wird im Statement-Cache gesucht, wie wird Äquivalenz von SQL-Anweisungen festgestellt? • Wie lange wird im Cache aufgehoben (nur bis Transaktionsende oder länger?) Datenbanksysteme 2 73 8.8 Abschließendes zum Thema „Anwendungsprogrammierung“ • Wie immer: Eine Programmiersprache lernt man nicht allein aus Vorlesungen, sondern durch eigenes Üben; dies gilt auch für embedded SQL! • Lektüre des ausgeteilten Papiers „Kopplungsarten von Programmiersprachen und Datenbanksprachen“ (K. Neumann, TU Braunschweig) ist Pflicht! Enthält Ausführungen u.a. zu: - „Impedance mismatch“ zwischen Deskriptivität/Mengenorientierung auf seiten der DB-Sprache und Prozeduralität/Satzorientierung in Prog.sprache - Andere Kopplungsarten à la • Prozedurale Schnittstelle („Call Level Interface“), bekannt u.a. von IMS, aber auch bei relationalen DBVSen (sogar zunehmend) ein Thema Microsoft ODBC (Open Data Base Connectivity) Datenbanksysteme 2 74 • Einfache Programmiersprachen- (und Übersetzer-)Erweiterungen, bekannt vor allem von COBOL/CODASYL (Zugriff aus COBOL-AP auf ´Netzwerkdatenbanksystem´) • Datenbankprogrammiersprachen: Versuch einer besseren Integration von Programmiersprache und Datenbanksprache; z.B. Datentyp Relation in Sprache Pascal oder Modula (bisher – schon sehr lange – nur Forschung (Prototypen), keine Produkte, keine Norm) • 4GL-Sprachen („Fourth Generation Language“): „Hohe“ Programmiersprachen, die u.a. Datenbankzugriff, Reportgenerator etc. etc. beinhalten. Beispiele: ABAP (SAP), NATURAL (Software AG), INGRES-4GL (Computer Associates) u.v.a.m. Produktivitätssteigerung, aber auch „Abhängigkeit“, da Anwendungen nicht portabel! Neumann-Beitrag selbst lesen, eigene Gedanken dazu machen!! Datenbanksysteme 2 75 Zusammenfassung / ´Hilites´ zum Thema Anwendungsprogr. mit eingebettetem SQL (embedded SQL, eSQL) • In der Praxis wird vorwiegend aus Anwendungsprogr. auf relationale Datenbanken zugegriffen; Ad-hoc-Zugriff (interaktives SQL) ist aus Praxissicht somit eher die Ausnahme • Problem: Wie Programm (Prog.sprache) einerseits und SQL-Anweisung(en) (DB-Sprache) andererseits „verheiraten“? • Impedance Mismatch durch Mengenorientierung (SQL) vs. Satzorientierung (Progr.Sprache) deskriptiv (SQL) vs. navigierend (Progr.Sprache) • Embedded SQL (eSQL) als eine mögliche (weitverbreitete) Lösung • eSQL basiert auf Vorübersetzeransatz (Pre-compilation) • Markierung von DBMS-relevanten Programmteilen durch EXEC SQL Präfix (Programmteile = Einzelanweisungen oder Programmblöcke) Regularien hinsichtlich der Strukturierung eines Programms mit eSQL • Vorübersetzer (Pre-compiler) braucht nicht komplette Programmiersprachensyntax beherrschen (und auch nicht Programm komplett parsen) erhöht Unabhängigkeit des Vorübersetzers von Programmiersprachensyntax und steigert Effizienz der Vorübersetzung Datenbanksysteme 2 76 • Unterscheidung zwischen deklarativen und ausführbaren eSQLAnweisungen • Wichtig: Cursor-Konzept kümmert sich um Impedance Mismatch als „Brücke“ zw. Programm und DBMS • Alle Arten von DB-Anweisungen (SQL) können auch aus Programm heraus verwendet werden (SFW, UPDATE, DELETE, INSERT (also DML-Anweisungen) und auch DDL-Anweisungen) • Problem bei diesem statischen eSQL: DB-Anweisungen müssen zum Programmierzeitpunkt/Vorübersetzungszeitpunkt fest im Programm „verdrahtet“ sein (bis auf gewisse (geringe) Flexibilität durch Verwendung von Host-Variablen in eSQL-Anweisungen) d.h. vor allem (auch), Struktur eines Anfrageergebnisses (Relationenschema) muss bei Programmierung/Vorübersetzung bereits fixiert werden verhindert flexible Programmierung und „generische“ Programme • Lösung: Dynamisches eSQL: Erst zur Programmlaufzeit müssen SQL-Anweisungen im Programm festliegen wesentlich höhere Flexibilität als bei statischem eSQL als Vorteil Datenbanksysteme 2 77