8. SQL zur Anwendungsprogrammierung (embedded SQL, ESQL

Werbung
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
Herunterladen