Eine Datenbankverbindung kann mit Hilfe eines Queries SQL-Anweisungen an die Datenbank senden, ausführen und die Ergebnisse der Anweisungen abholen.
Ein allgemeines Beispiel zur Verwendung der Klasse query finden sie hier.
Eine Datenbankverbindung kann mit Hilfe eines Queries SQL-Anweisungen an die Datenbank senden, ausführen und die Ergebnisse der Anweisungen abholen. Zu einer Datenbankverbindung können beliebig viele, auch geschachtelte Queries geöffnet werden.
Query erfordert #include "internal/types.h"
Das folgende allgemeine Schema gilt für alle Queries :
Queries werden mit dem Befehl sql::query erzeugt.
static int query::send(Query qu, char* cmd_part)
Senden einer SQL-Anweisung oder Teilen einer SQL-Anweisung. Die SQL-Anweisungen sollten an Stelle von Eingabewerten Platzhalter beinhalten. Platzhalter für Eingabewerte (input) können in zwei Formen angegeben werden :
Werden Strings gebunden, müssen um die Werteplatzhalter keine Anführungszeichen geschrieben werden. Ebenso ist es nicht nötig, Anführungszeichen in den Strings zu maskieren.
Alle mit send weitergegebenen Anweisungen werden im Query gesammelt und bei exec als eine Anweisung ausgeführt. Nach dem Ausführen der Anweisung wird der Anweisungspuffer im Query geleert. Ebenso werden nach dem Ausführen die Bindungen an die Eingabewerte wieder gelöst.
Zu Besonderheiten der Verwendung von query::send bei SOAP Datenverbindungen siehe unter SOAP.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
cmd_part | String oder char* | - | Anweisung oder Teil einer SQL-Anweisung |
static int query::isend(Query qu, int i)
Senden einer int-Zahl an einen SQL Query. Die Funktion ist analog der Funktion query::send mit der Änderung, dass nicht ein String, sondern eine Ganzzahl gesendet wird. Die Wirkung des Befehles lässt sich am einfachsten so beschreiben : Die übergebene Zahl wird als Text an den bisherigen Anweisungstext des Queries angehangen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
i | int | - | Ganzzahl, die an den Query gesendet wird. |
static int query::fsend(Query qu, float f)
Senden einer float-Zahl an einen SQL Query. Die Funktion ist analog der Funktion query::send mit der Änderung, dass nicht ein String, sondern eine Kommazahl gesendet wird. Die Wirkung des Befehles lässt sich am einfachsten so beschreiben : Die übergebene Zahl wird als Text an den bisherigen Anweisungstext des Queries angehangen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
f | float | - | Kommazahl, die an den Query gesendet wird. |
static int query::input(
Query qu,
int type,
char* value,
int fsize = 0,
char* ftype = "JPEG")
Binden eines int-Wertes an den entsprechenden Wertplatzhalter im SQL-Befehl.
Wird eine Variable gebunden, muss sichergestellt sein, dass diese Variable zur Ausführzeit der Anweisung noch existiert.
Die Angabe des zweiten Parameter ist zwingend und muss zum Datentyp des zugehörigen Attributes passen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay 0 = Fehler |
|
qu | Query | - | Ein mit sql::query geöffneter Query. |
type | int | - | Typ des Wertes. Der Datentyp, der zu einem
Variablenplatzhalter gehört, ergibt sich aus der jeweiligen SQL-Anweisung.
Es ist Aufgabe des Skriptprogrammierers, die richtigen
Wertetypen zu binden. kInt kFloat kString kImage kBinfile : Pfad der Datei |
value | depends | - | Dieser Wert wird an Stelle des zugehörigen Variablenplatzhalters (? oder :n)
an die Datenbank gesendet. Der Typ des Parameters hängt vom Wert type ab.
Passen type und Datentyp von value nicht zusammen, kann das zum Absturz von InDesign® oder zu
unerwarteten Daten auf der Datenbank führen! kInt: int, short, long (z.B -1, 0, 1, 2) kFloat : float, real (z.B. -1.0, 1.0, 1.1) kString : String oder char* (z.B. "", "paul") kImage : Image, Beispiel siehe unten kBinfile : char*, Beispiel siehe unten, Ist die Angabe leer (0 oder ""), wird das Zieldatenbankfeld mit dem leeren Blob definiert. |
⇨ Beim Sichern von Dateien (type = kBinfile) kann gewählt werden, ob die Datei im Original oder ein Preview der Datei gesichert werden soll. (Previews gehen natürlich nur von Bilddateien!). Beim Sichern von Previews können Rahmengröße und Format gewählt werden. Die folgenden Parameter sind nur für type = kBinfile gültig. Es wird immer versucht, die max. Farbtiefe (24) zu verwenden. Bilder werden immer in Bildschirmauflösunf (72 dpi) erzeugt. | |||
fsize | int | kCopyLocalFile | Was soll gesichert werden? kCopyLocalFile : Originaldatei kOriginalSize : Preview in originaler Bildgröße > 0 : größe (in Punkten) eines quadratischen Rahmens für das Preview |
ftype | String oder char* | "JPEG" | Bildformat des Previews. Die zulässigen Formate finden sie hier. "origin" : Datei 1:1 übertragen (seit Comet 3.1 R2014, 19. Juli 2010) |
Sei folgender Befehl gesendet
select name, age, cv from persons where name like ? and age > ?
Dann werden Eingabebindungen der folgenden Art erwartet:
query::input (qu, kString, "Paul%"); query::input (qu, kInt, 10);
Um ein Preview einer Bilddatei auf die Datenbank zu schreiben, können Sie zwischen zwei Mögllichkeiten wählen. Das erste Skript erzeugt das Preview selbst. Sie können neben der Größe und dem Bildtyp des Previews auch dessen Auflösung und Farbtiefe bestimmen. Im zweiten Skript wird der Preview intern berechnet. In diesem Fall sind Farbtiefe (24) und Auflösung (72 dpi) vorgegeben
//Preview erzeuegen und schreiben int main () { DBC dbc = sql::connection (); Query qu = sql::query (dbc); Image img = image::alloc ("$DESKTOP/clara.JPG"); Image prv = image::preview (img, 140, 72, 24, "PICT");
query::send (qu, "update pageitems set preview = ? where id = ?"); query::input (qu, kImage, prv); query::input (qu, kInt, 17); query::exec (qu);
image::release (img); image::release (prv); query::close (qu);
return 0; }
//Preview on the fly erzeugen int main () { DBC dbc = sql::connection (); Query qu = sql::query (dbc);
query::send (qu, "update pageitems set preview = ? where id = ?"); query::input (qu, kBinfile, "$DESKTOP/clara.JPG" 140, "PICT"); query::input (qu, kInt, 17); query::exec (qu);
query::close (qu);
return 0; }
Hole das Preview eines Templates aus der aktuellen Datenbank und sichere es auf den Schreibtisch.
#include "internal/types.h" #include "internal/text.h" int main () { Query qu = sql::query (sql::dbconnection ()); Image img = 0;
/// Init if (!qu) { showmessage ("No database connction"); return 0; }
img = image::alloc ();
// Retreive image query::send (qu, "select preview from pageitems where ID = 15"); query::output (qu, kImage, img); if (!query::exec(qu)) { query::close (qu); image::release (img); return 0; } while (query::fetch (qu)) {} query::close (qu);
// Save image file wlog ("", "Size of image : %d\n", image::bytes (img)); image::save (img, "$DESKTOP/aaa/pageitem15.jpg", 1); image::release (img);
return 0; }
static int query::output(
Query qu,
int type,
int* result)
Definiere eine int-Ausgabevariable für die n-te Spalte einer select-Anweisung. Die Definition der Variablen muss Typ und Reihenfolge den Ausgabespalten entsprechen. Es ist nicht nötig, alle Ausgabespalten zu definieren, aber wenn sie die Ergebisse der n-ten Spalte erhalten wollen, müssen alle vorangehenden n-1 Spalten definiert sein.
Obwohl Oracle einen deutlichen Unterschied macht zwischen Strings und Texten können sie diese Unterscheidung in Skripten vernachlässigen. Es ist unerheblich, ob sie einen varchar2-Wert oder einen CLOB senden, alle nötigen Unterscheidungen kann cscript selbständig treffen.
Wird eine Ausgabevariable definiert, muss sichergestellt sein, dass diese Variable zur Ausführzeit der Anweisung noch existiert. Die Angabe des zweiten Parameter kInt ist zwingend, andere Angaben führen zu schwerwiegenden Fehlern in der Skriptverarbeitung und können InDesign® zum Absturz bringen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
type | int | - | Datentyp der zugehörigen Spalte, hier muss kInt stehen. Der Datentyp, der zu einer Variable gehört, ergibt sich aus der jeweiligen SQL-Anweisung. Es ist Aufgabe des Skriptprogrammierers, die richtigen Variablentypen zu definieren. |
result | int* | - | Wert einer Ergebniszeile |
Sei folgender Befehl gesendet
select name, age, cv from persons where name like ? and age > ?
Dann können Wertedefinitionen der folgenden Art gemacht werden:
char name[256]; int age char *cv = 0; : cv = alloc (50000+1); : query::output (qu, kString, name); query::output (qu, kInt, &age); query::output (qu, kString, cv, 50000); : release (cv);
Mit einem kleinen Trick können Sie auch den Inhalt von Datenbank-Blobs abholen und eine Datei schreiben. Das geht mit Hilfe des Datentyp-Bezeichners kImage. Achten Sie darauf, dass Blobdaten und Dateiendung zueinander passen.
#include "internal/types.h"
int main () { DBC dbc = sql::connection (); Query qu = sql::query (dbc); Image img = image::alloc ();
query::send (qu, "select preview from comet_preview where id = 1"); query::output (qu, kImage, img); query::exec (qu); while (query::fetch (qu)) {} query::close (qu);
wlog ("", "Size of image : %d\n", image::bytes (img)); image::save (img, "$DESKTOP/aaaPPP.indd", 1); image::release (img);
return 0; }
static int query::output(
Query qu,
int type,
float* result)
Definiere eine float-Ausgabevariable für die n-te Spalte einer select-Anweisung. Die Definition der Variablen muss Typ und Reihenfolge den Ausgabespalten entsprechen. Es ist nicht nötig, alle Ausgabespalten zu definieren, aber wenn sie die Ergebisse der n-ten Spalte erhalten wollen, müssen alle vorangehenden n-1 Spalten definiert sein. Wird eine Ausgabevariable definiert, muss sichergestellt sein, dass diese Variable zur Ausführzeit der Anweisung noch existiert. Die Angabe des zweiten Parameter kFloat ist zwingend, andere Angaben führen zu schwerwiegenden Fehlern in der Skriptverarbeitung und können InDesign® zum Absturz bringen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
type | int | - | Datentyp der zugehörigen Spalte, hier muss kFloat stehen. Der Datentyp, der zu einer Spalte gehört, ergibt sich aus der jeweiligen SQL/SOAP-Anweisung. Es ist Aufgabe des Skriptprogrammierers, die richtigen Variablentypen zu definieren. |
result | float* | - | Wert einer Ergebniszeile |
static int query::output(
Query qu,
int type,
char* result,
int max_len =0)
Definiere eine String-Ausgabevariable für die n-te Spalte einer select-Anweisung. Die Definition der Variablen muss Typ und Reihenfolge den Ausgabespalten entsprechen. Es ist nicht nötig, alle Ausgabespalten zu definieren, aber wenn sie die Ergebisse der n-ten Spalte erhalten wollen, müssen alle vorangehenden n-1 Spalten definiert sein.
Obwohl Oracle einen deutlichen Unterschied macht zwischen Strings und Texten können sie diese Unterscheidung in Skripten vernachlässigen. Es ist unerheblich, ob sie einen varchar2-Wert oder einen CLOB erhalten, alle nötigen Unterscheidungen kann cscript selbständig treffen. Wichtig für sie ist lediglich, dass genügend Speicher für die Rückgabe reserviert ist.
Wird eine Ausgabevariable definiert, muss sichergestellt sein, dass diese Variable zur Ausführzeit der Anweisung noch existiert. Die Angabe des zweiten Parameter kString ist zwingend, andere Angaben führen zu schwerwiegenden Fehlern in der Skriptverarbeitung und können InDesign® zum Absturz bringen.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
type | int | - | Datentyp der zugehörigen Spalte, hier muss kString stehen. Der Datentyp, der zu einer Spalte gehört, ergibt sich aus der jeweiligen SQL/SOAP-Anweisung. Es ist Aufgabe des Skriptprogrammierers, die richtigen Variablentypen zu definieren. |
result | String oder char* | - | Wert einer Ergebniszeile |
max_len | int | 4001 | Maximallänge des Ergebnisses. Ist das Ergebis länger wird es auf diese Länge gekürzt. Wenn result vom Typ String ist, wird dieser Parameter ignoriert. Mit einem auf 100 Zeichen allokierten String und der Angabe 10 können Sie 9 Zeichen von der Datenbank abholen, das letzte Zeichen wird für die den String abschließende 0 benötigt. Ist max_len größer als die Anzahl der allokierten Bytes für result, kann InDesign® abstürzen, wenn Ergebnisse länger als max_len sind. Das gilt insbesondere dann, wenn max_len nicht angegeben ist. In diesem Fall sollte result mindestens 4001 Bytes reserviert bekommen. In Unicode-Datenbanken darf der Wert höchstens (allokierte Länge -1) / 8 betragen. Die Angabe steuert nämlich auch, wieviele Zeichen von der Datenbank geholt werden. Und jedes Unicode-Zeichen kann intern acht Zeichen belegen (<0x00FC>). |
In beiden Fällen ist result genügend groß definiert. Im zweiten Fall werden max. 124 Zeichen abgeholt.
char * result = alloc (4001);
query::output (qu, kString, result);
char * result = alloc (125);
query::output (qu, kString, result, 125);
static int query::exec(Query qu, int replaceBindings = 1)
Die gesendeten Befehlsteile werden als eine Anweisung an die Datenbank geschickt. Danach werden alle Werteplatzhalter im Befehl durch die angegeben Eingabewerte ersetzt und der Befehl ausgeführt. Nachdem der Befehl ausgeführt wurde, wird der Befehlspuffer geleert und alle Bindungen zu den Eingabewerten werden gelöst.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Okay | |
Return | int | 0 = Fehler | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
replaceBindings | int | 1 | Sollen vor der Ausführung die Wertplatzhalter (?) im Befehl ersetzt werden? 1 : Ja (empfohlen) 0 : Nein. Der Wert wird nur in SOAP-Verbindungen verwendet. Fragezeichen (?) im Befehl werden in diesem Fall nicht ersetzt und möglicherweise mit query::input gebundene Eingabevariablen werden ignoriert. |
static int query::fetch(Query qu)
Hole die nächste Zeile von Ergebnissen des Datenbankbefehles ab. Der Befehl sollte nach jedem Befehl, von dem Ergebnisse erwartet werden, in einer Schleife solange gerufen werden, bis er 0 liefert. Nachdem die letzten Daten abgeholt worden, werden alle Bindungen zu den Ausgabevariablen gelöst. Der Query kann jetzt für die Bearbeitung eines weiteren Befehles verwendet werden.
Name | Typ | Default | Beschreibung |
Return | int | 1 = Eine Ergebniszeile wurde abgeholt | |
Return | int | 0 = keine weiteren Ergebnisse | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
Sei folgender Befehl gesendet
select name, age, cv from persons where name like ? and age > ?
Dann können Ergebnisse wie folgt abgeholt werden:
char name[256]; int age char *cv = 0; : cv = alloc (50000+1); : query::output (qu, kString, name); query::output (qu, kInt, &age); query::output (qu, kString, cv, 50000);
while (query::fetch (qu)) { // name, age und cv enthalten jetzt aktuelle Werte }
release (cv);
static int query::close(Query qu)
Schließen eines Queries. Jeder geöffnete Query muss mit close wieder geschlossen werden.
Name | Typ | Default | Beschreibung |
qu | Query | - | Ein mit sql::query geöffneter Query. |
static int query::commit(Query qu, char* message = 0)
Bestätigen der Änderungen eines Queries.
Name | Typ | Default | Beschreibung |
Return | int | 0 oder Fehlercode | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
message | String oder char* | 0 | Beschreibender Text für die Aktion |
static int query::rollback(Query qu, char* message = 0)
Änderungen eines Queries rückgängig machen.
Name | Typ | Default | Beschreibung |
Return | int | 0 oder Fehlercode | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
message | String oder char* | 0 | Beschreibender Text für die Aktion |
static int query::set_method(Query qu, char* method)
Setze die SOAP call Methode des Queries. SOAP-Aufrufe an
call erwarten einen Methodennamen und einen Befehlsstring. Den Befehlsstring setzen
sie mit send.
Ab R380 kann das query::new_query und query::set_method als soap::call zusammengefasst werden.
Name | Typ | Default | Beschreibung |
Return | int | 0 oder Fehlercode | |
qu | Query | - | Ein mit sql::query geöffneter Query. |
method | String oder char* | - | Methode, die von call ausgeführt werden soll. |
static char* query::get_command(Query qu, int replaceBinds = 0)
Vollständige Anweisung, die bisher an den Query gesendet (aber nicht ausgeführt) wurde.
Name | Typ | Default | Beschreibung |
Return | char* | Vollständige Anweisung, die bisher an den Query gesendet wurde. "" : Fehler oder noch nichts gesendet Der Rückgabewert darf nicht verändert werden und wird bei folgenden Aufrufen der Funktion überschrieben. Hier finden Sie Informationen zu readonly-Rückgaben von Funktionen. |
|
qu | Query | - | Ein mit sql::query geöffneter Query. |
replaceBinds | int | 0 | Sollen die ?-Platzhalter in der Anweisung durch ihre aktuellen Werte ersetzt werden? 0 : Nein 1 : Ja. Die ? können nur soweit ersetzt werden, wie mit query::input auch Werte definiert wurden! |
#include "internal/types.h"
main () { Query qu; char name[512]; int id;
// Öffnen qu = sql::query (sql::dbconnection ()); if (!qu) return 0;
// Befehl senden query::send (qu, "select name, id from pageitems where "); query::send (qu, "name like ?");
// Eingabewerte binden query::input (qu, kString, "a%");
// Ausgabevariablen definieren query::output (qu, kString, name); query::output (qu, kInt, &id); // Adress-Operator beachten!
// Ausführen if (query::exec (qu)) { // Ergebnisse abholen while (query::fetch (qu)) { // Do something with name and id showmessage ("%d\t%s", id, name); } }
// Aufräumen query::close (qu);
return 0; }
Alphabetic index HTML hierarchy of classes or Java