Das ursprüngliche Ziel der Entwickler von Embedded SQL war der Entwurf einer Sprache, die sowohl interaktiv nutzbar als auch in 3.Generationssprachen einbettbar sein sollte. Mit Embedded SQL erreicht man eine Datenbankanbindung bestehender 3. Generationssprachen. Embedded SQL erlaubt die Spezifikation von SQL-Anweisungen zur Laufzeit und bietet Kompatibilität zu anderen relationalen Datenbanksystemen durch den ANSI-Standard. Im Gegensatz zu PL/SQL hat man auch die Möglichkeit, die Ergebnisse in ansprechender Form auszugeben. Das entstehende Programm ist allerdings eng an die Datenbankstruktur gebunden.
In Embedded SQL werden SQL Befehle in normale Programme (Hostprogramme, geschrieben in einer beliebigen Hostsprache wie COBOL, Pascal oder C) eingefügt. Diese Befehle beginnen und enden dabei mit speziellen Anfangs- und Endsequenzen (zum Beispiel Beginn mit "`EXEC SQL"' und Ende mit "`;"'). Ein Precompiler übersetzt die SQL Befehle in äquivalenten Quellcode, sodaß das Programm zum Beispiel nur mehr C-Code enthält und anschließend mit einem normalen C-Compiler übersetzt werden kann. Folgende Anweisungen sind in Embedded SQL erlaubt:
Das nächste Beispiel bestimmt den Vornamen des Autors White. Wenn ein Vorname gefunden wurde, wird dieser ausgegeben.
{
EXEC SQL BEGIN DECLARE SECTION;
char firstName[50];
char lastName[] =
unsigned short firstNameNull;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO server USER login.password;
EXEC SQL SELECT auFirstName INTO :firstName :firstNameNull
FROM Authors WHERE auLastName = :lastName;
if (firstNameNull
return (0);
}
nnnnnn¯
main()
"
White"
;
<>
-1) printf("%s %s"
, firstName, lastName);
In Embedded SQL verwendet man Hostvariablen zur Kommunikation der Daten zwischen der Datenbank und dem Anwendungsprogramm ( firstName, lastName). Innerhalb von SQL-Anweisungen wird den Hostvariablen ein "`:"' vorangestellt, um sie von Datenbank-Objekten wie Tabellen oder Spalten mit demselben Namen unterscheiden zu können. Hostvariablen kann man optional Indikatorvariablen ( firstNameNull) zuordnen, indem man sie in der SQL-Anweisung direkt hinter die eigentliche Hostvariable schreibt. Indikatorvariablen zeigen an, ob der Wert der Hostvariablen ein Nullwert ist oder ob zum Beispiel bei der Zuweisung Werte abgeschnitten wurden.
Im folgenden wird eine kurze Übersicht über die einzelnen Embedded SQL-Befehle gegeben.
nnnnnn¯ CONNECT TO [serverName.]databaseName [AS connectionName]CONNECT baut eine Verbindung zum angegebenen SQL-Server auf und gibt ihr den angegebenen Namen.USER login[.password]
nnnnnn¯ DISCONNECT [connectionName CURRENT ALL]DISCONNECT schließt die angegebene, die aktuelle oder alle Verbindungen.
nnnnnn¯ SET CONNECTION connectionNameSET CONNECTION macht die angegebene Verbindung zur aktuellen Verbindung.
nnnnnn¯ DECLARE cursorName CURSOR FOR (selectStmt preparedStmt)DECLARE CURSOR deklariert einen Cursor zum zeilenweisen Abfragen der Ergebnisse der SQL-Anweisung.
nnnnnn¯ Beispiel: EXEC SQL DECLARE C1 CURSOR FORSELECT auFirstName, auLastName FROM Authors FOR BROWSE;
nnnnnn¯ OPEN cursorName [(USING DESCRIPTOR :sqldaOPEN liest den ersten Datensatz der Ergebnismenge der SQL-Anweisung, die zu dem angegebenen Cursor gehört. Für zur Laufzeit erstellte SQL-Anweisungen muß man eine SQLDA (SQL Descriptor Area) Struktur übergeben. Wenn die SQL-Anweisung des Cursors Parameter-Platzhalter ("`?"') enthält, muß man für jeden Platzhalter eine Hostvariable angeben.:hostVar {
"
,"
:hostVar})]
nnnnnn¯ FETCH cursorName [(USING DESCRIPTOR :sqldaFETCH liest den nächsten Datensatz der Ergebnismenge der SQL-Anweisung, die zu dem angegebenen Cursor gehört.INTO :hostVar {, :hostVar })]
nnnnnn¯ Beispiel:EXEC SQL DECLARE C1 CURSOR FOR
SELECT auFirstName, auLastName FROM Authors FOR BROWSE;
EXEC SQL OPEN C1;
while (SQLCODE == 0)
{
EXEC SQL FETCH C1 INTO :firstName, :lastName;
printf(
"%s %s"
, firstName, lastName);}
nnnnnn¯ SELECT [selectList] INTO :hostVar {SELECT liest die angegebenen Ergebnisse der SQL-Anweisung in die Hostvariablen ein. Liefert die SQL-Anweisung mehr als eine Ergebniszeile, wird ein Fehler gemeldet."
,"
:hostVar} selectOptions
nnnnnn¯ Beispiel: EXEC SQL SELECT auLastName INTO :name FROM AuthorsWHERE storID = :id;
nnnnnn¯ DESCRIBE preparedStmt INTO :sqldaDESCRIBE füllt Einträge in der Datenstruktur sqlda mit Informationen über die vorbereitete SQL-Anweisung.
nnnnnn¯ Beispiel:
#
define NumReturnCols 2struct sqlda *mysqlda;
EXEC SQL BEGIN DECLARE SECTION;
char statement[] =
"
SELECT auFirstName, auLastName FROM Authors"
;EXEC SQL END DECLARE SECTION;
mysqlda = malloc(SQLDASIZE(NumReturnCols));
mysqlda-
>
sqln = NumReturnCols;mysqlda-
>
sqldabc = SQLDASIZE(NumReturnCols);EXEC SQL DECLARE C1 CURSOR FOR stmt1;
EXEC SQL PREPARE stmt1 FROM :statement;
EXEC SQL DESCRIBE stmt1 INTO :mysqlda;
EXEC SQL OPEN C1;
EXEC SQL FETCH C1 USING DESCRIPTOR :mysqlda;
nnnnnn¯ PREPARE stmtName [INTO :sqlda] FROM :hostVarPREPARE bereitet die SQL-Anweisung, die als Zeichenkette in der angegebenen Hostvariable steht, zur Ausführung vor und assoziiert den angegebenen Namen mit dieser SQL-Anweisung.
nnnnnn¯ Beispiel:EXEC SQL BEGIN DECLARE SECTION;
char prep[] =
"
insert into table values(?,?,?)"
;char name[30];
char car[30];
double num;
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE prepStat FROM :prep;
while (SQLCODE == 0)
{
strcpy(name,
"
Elaine"
);strcpy(car,
"
Lamborghini"
);num = 4.9;
EXEC SQL EXECUTE prepStat USING :name, :car, :num;
}
nnnnnn¯ EXECUTE preparedStmt [(USING DESCRIPTOR :sqldaEXECUTE führt die vorbereitete SQL-Anweisung aus, wobei die Hostvariable sqlda beschreibende Informationen enthält, und für jeden Parameter-Platzhalter ("`?"') in der SQL-Anweisung eine weitere Hostvariable angegeben werden muß.:hostVar {
"
,"
:hostVar})]
nnnnnn¯ EXECUTE IMMEDIATE :stmtEXECUTE IMMEDIATE führt die SQL-Anweisung aus, die als Zeichenkette in der angegebenen Hostvariablen steht.
nnnnnn¯ DELETE [FROM] (tableName viewName)DELETE löscht den Datensatz, über dem der angegebene Cursor gerade steht, oder alle Datensätze, die die angegebene Bedingung erfüllen.WHERE (CURRENT OF cursorName searchConditions)
nnnnnn¯ UPDATE (tableName viewName) SET (colUPDATE ändert den Datensatz, über dem der angegebene Cursor gerade steht, oder alle Datensätze, die die angegebene Bedingung erfüllen."
="
expr) {"
,"
(col"
="
expr) }WHERE CURRENT OF cursorName
UPDATE (tableName viewName)
SET [tableName. viewName.] columnName
"
="
(expr NULL "`("'selectStatement"`)"')
{, (expr NULL "`("'selectStatement"`)"')}
[FROM (tableName viewName) {, (tableName viewName)}]
[WHERE searchCondition]
nnnnnn¯ CLOSE cursorNameCLOSE schließt den angegebenen Cursor, wobei nichtbearbeitete Daten verworfen werden.
nnnnnn¯ WHENEVER (NOT FOUND SQLERROR SQLWARNING)WHENEVER legt fest, was beim Auftreten eines Fehlers passieren soll.(CONTINUE GOTO stmtLabel CALL function() )