Für Parameter von SQL-Anweisungen kann an Platzhalter angeben, die bei der Ausführung durch Variablenwerte ersetzt werden. Solche Platzhalter werden durch "`?"' ausgedrückt, z.B.:
nnnnnnnn¯
stat := SQL.PrepareStatement(conn,
"
INSERT INTO Friends VALUES (?, ?, ?, ?, ?)"
);
Vor der Ausführung muß der Programmierer an jeden Platzhalter eine Variable binden. Anschließend kann er den Variablen Werte zuweisen und die Anweisung mittels SQL.Execute ausführen.
Variablen können mittels SQL.BindParameters an Platzhalter gebunden werden. Dabei muß für jeden Platzhalter ein Record vom Typ SQL.ParamDesc aufgebaut werden, das den Typ des Parameters beschreibt, z.B.:
...
(* assume that parameter 0 is a string *)
types[0].type := stringType; types[0].mapType := stringMapType;
types[0].inOut := SQL.InParam; types[0].name :=
... do the same for the other parameters
SQL.BindParameters(stat, types, 5);
nnnnnnnn¯
VAR types: ARRAY 5 OF SQL.ParamDesc; (* description of placeholders *)
"
firstName"
;
stringType und stringMapType müssen an geeigneter Stelle (z.B. nach dem Aufbau der Verbindung zur Datenbank) initialisiert werden. Wenn der Datentyp stringType umgesetzt werden konnte, liefert SQL.Map TRUE, und stringMapType ist der umgesetzte Datentyp, z.B.:
IF ~SQL.Map(conn, stringType, stringMapType) THEN HALT(69) END ;
nnnnnnnn¯
stringType.sqlType := SQL.OberonChar; stringType.prec := 32; stringType.scale := 0;
Nun können den Parametern Werte zugewiesen werden. SQL.BindParameters legt für jeden Parameter ein Feld vom Typ SQL.Field an. Die Parameterwerte müssen in diese Felder kopiert werden, z.B.:
...
SQL.FindField(stat.params,
COPY(firstName, field(SQL.StringField).str);
nnnnnnnn¯
VAR field: SQL.Field; firstName: ARRAY 32 OF CHAR;
"
firstName"
, field); (* get field of parameter 0 (firstName) *)
Wenn alle Felder mit Werten belegt sind, kann die Anweisung schließlich ausgeführt werden:
nnnnnnnn¯
SQL.Execute(stat)
Folgendes Beispiel zeigt diese Aktionen nochmals in ihrem Zusammenhang:
VAR
stringType, stringMapType, longintType, longintMapType: SQL.Type;
...
(* after connecting to the database *)
stringType.sqlType := SQL.OberonChar; stringType.prec := 32; stringType.scale := 0;
IF ~SQL.Map(conn, stringType, stringMapType) THEN HALT(69) END ;
longintType.sqlType := SQL.OberonLongInt; longintType.prec := 0; longintType.scale := 0;
IF ~SQL.Map(conn, longintType, longintMapType) THEN HALT(69) END ;
...
PROCEDURE Insert*;
VAR firstName, lastName, street, town: ARRAY 32 OF CHAR; zipCode: LONGINT;
stat: SQL.Statement; field: SQL.Field; types: ARRAY 5 OF SQL.ParamDesc;
BEGIN
In.Open; In.String(firstName); In.String(lastName); In.String(street);
In.String(town); In.LongInt(zipCode);
stat := SQL.PrepareStatement(conn,
types[0].type := stringType; types[0].mapType := stringMapType;
types[0].inOut := SQL.InParam;
types[1] := types[0]; types[2] := types[0]; types[3] := types[0];
types[0].name :=
types[2].name :=
types[4].type := longintType; types[4].mapType := longintMapType;
types[4].inOut := SQL.InParam;
types[4].name :=
SQL.BindParameters(stat, types, 5);
SQL.FindField(stat.params,
COPY(firstName, field(SQL.StringField).str);
SQL.FindField(stat.params,
COPY(lastName, field(SQL.StringField).str);
SQL.FindField(stat.params,
COPY(street, field(SQL.StringField).str);
SQL.FindField(stat.params,
COPY(town, field(SQL.StringField).str);
SQL.FindField(stat.params,
field(SQL.IntField).i := zipCode;
SQL.Execute(stat)
END Insert;
nnnnnnnn¯
(* global variables *)
"
INSERT INTO Friends VALUES (?, ?, ?, ?, ?)"
);
"
firstName"
; types[1].name := "
lastName"
;
"
street"
; types[3].name := "
town"
;
"
zipCode"
;
"
firstName"
, field);
"
lastName"
, field);
"
street"
, field);
"
town"
, field);
"
zipCode"
, field);