Unter Embedded SQL versteht man die Einbettung von SQL-Befehlen innerhalb eines Anwendungsprogramms. Das Anwendungsprogramm heißt Host Programm, die in ihm verwendete Sprache heißt Host-Sprache.
Der Microsoft SQL-Server unterstützt Embedded SQL im Zusammenspiel mit den Programmiersprachen C und C++ durch einen Pre-Compiler. Abbildung 9.6 zeigt den prinzipiellen Ablauf: Das mit eingebetteten SQL-Statements formulierte Host-Programm beispiel.sqc wird zunächst durch den Pre-Compiler unter Verwendung von SQL-spezifischen Include-Dateien in ein ANSI-C-Programm beispiel.c überführt. Diese Datei übersetzt ein konventioneller C-Compiler unter Verwendung der üblichen C-Include-Files in ein Objekt-File beispiel.o. Unter Verwendung der einer Runtime Library wird daraus das ausführbare Programm beispiel.exe gebunden.
Eingebettete SQL-Statements werden durch ein vorangestelltes EXEC SQL gekennzeichnet und ähneln ansonsten ihrem interaktiven Gegenstück.
Die Kommunikation zwischen dem Host-Programm und der Datenbank geschieht über sogenannte Host-Variablen, die im C-Programm deklariert werden. Eine Input-Host-Variable überträgt Daten des Hostprogramms an die Datenbank, eine Output-Host-Variable überträgt Datenbankwerte und Statusinformationen an das Host-Programm. Hostvariablen werden innerhalb von SQL-Statements durch einen vorangestellten Doppelpunkt (:) gekennzeichnet.
Für Hostvariablen, die Datenbankattributen vom Typ VARCHAR entsprechen, empfiehlt sich eine Definition nach folgendem Beispiel:
char fachgebiet[20];
Mit einer Hostvariable kann eine optionale Indikator-Variable assoziiert sein, welche Null-Werte überträgt oder entdeckt. Folgende Zeilen definieren alle Hostvariablen zum Aufnehmen eines Datensatzes der Tabelle Professoren sowie eine Indikator-Variable raum_ind zum Aufnehmen von Status-Information zur Raumangabe.
int persnr; char name [20]; char rang [3]; int raum; short raum_ind;
Folgende Zeilen transferieren einen einzelnen Professoren-Datensatz in die Hostvariablen persnr, name, rang, raum und überprüfen mit Hilfe der Indikator-Variable raum_ind, ob eine Raumangabe vorhanden war.
EXEC SQL SELECT PersNr, Name, Rang, Raum INTO :persnr, name, rang, raum INDICATOR :raum_ind FROM Professoren WHERE PersNr = 2125; if (raum_ind == -1) printf("PersNr %d ohne Raum \n", persnr);
Oft liefert eine SQL-Query kein skalares Objekt zurück, sondern eine Menge von Zeilen. Diese Treffer werden in einer sogenannten private SQL area verwaltet und mit Hilfe eines Cursors sequentiell verarbeitet.
EXEC SQL DECLARE C1 CURSOR FOR SELECT PersNr, Name, Rang, Raum FROM Professoren WHERE Rang='C4'; EXEC SQL OPEN C1; EXEC SQL FETCH C1 into :persnr, :name, :rang, :raum while (SQLCODE ==0){ printf("Verarbeite Personalnummer %d\n", persnr); EXEC SQL FETCH C1 into :persnr, :name, :rang, :raum } EXEC SQL CLOSE C1;
Listing 9.2 zeigt ein Embedded-SQL-Programm, die davon erzeugte Ausgabe zeigt Abb. 9.7.
Listing 9.2: Beispiel für embedded SQL