VOICE-Homepage: http://de.os2voice.org |
Juli 2004
Inhaltsverzeichnis
|
Von Wolfgang Draxler © Juli 2004 |
Heute werden wir den Versuch unternehmen, von REXX aus auf die Datenbank zuzugreifen. Dazu ist es notwendig, den Treiber für REXX herunterzuladen. Diesen Treiber findet man im Internet auf der Seite http://rexxsql.sourceforge.net/, im Bereich Download. Dort finden Sie die Datei rxsql24RC1_my_os2.zip. Laden Sie diese Datei herunter und speichern Sie sie in einem eigenen Verzeichnis. Als nächstes entpacken Sie diese Datei. Es sollten folgende Dateien entstehen:
Copying History Install Readme rexxmy.dll rexxmy.exe rexxsql.dll rexxsql.exe
und das Verzeichnis samples.
Die Dateien rexxmy.dll und rexxsql.dll kopieren wir in ein Verzeichnis, daß in der CONFIG.SYS-Anweisung LIBPATH angegeben worden ist, z.B. in das Verzeichnis \os2\dll.
Als nächstes erstellen wir ein eigenes Verzeichnis für die REXX-Programme. Ich verwende dazu das Verzeichnis P:\Rexx\mysql. Nun erstellen Sie in diesem Verzeichnis eine leere Datei namens ListLand.cmd und öffnen diese mit dem OS/2-Systemeditor.
Wie Sie im Artikel »DrDialog, oder wie ich lernte, REXX zu lieben« von Thomas Klein sicherlich schon gelesen haben, muß jedes REXX-Programm mit einer Kommentar-Zeile anfangen.
/* Programm: ListLand.cmd */ /* Autor: Wolfgang Draxler */ /* Datum: 05.05.2004 */
Als nächster Schritt müssen wir den Treiber rexxsql.dll in REXX einbinden. Dies geschieht
mittels der Befehle RxFuncAdd
und SQLLoadFuncs
.
Call RxFuncAdd "SQLLoadFuncs", "rexxsql", "SQLLoadFuncs" Call SQLLoadFuncs
Genauere Informationen zu den Befehlen finden Sie in der April-Ausgabe von Voice im Artikel »DrDialog, oder wie ich lernte, REXX zu lieben - Teil 12.
Im nächsten Schritt müssen wir eine Verbindung zur MySQL-Datenbank aufbauen. Diese geschieht mit dem
Befehl SQLConnect
.
Der Aufbau des Befehls ist folgender:
SQLCONNECT([Verbindungsname], [username], [passwort], [datenbank], [host])
Wenn SQLConnect
ein negatives Ergebnis liefert, hat der Verbindungsaufbau nicht funktioniert. Dies
kann beispielsweise passieren, wenn die Datenbank nicht läuft oder der User oder das Passwort falsch sind.
Es werden fünf Werte übergeben:
Für unser Beispiel sollte dann der Aufruf folgender sein, wobei Sie für das Passwort »<PW>« Ihr eigenes Root-Passwort eingeben müssen:
if SQLConnect("Conn", "root", "<PW>", "adressen", "localhost") < 0 then do say "Verbindungsaufbau hat nicht funktioniert" exit end
Für den Fall, daß ein Fehler auftritt, schreiben wir das REXX-Programm so, dass es sich korrekt von der Datenbank abmeldet und beendet. Zum korrekten Abmelden von der Datenbank gibt es den Befehl:
SQLDisconnect([Verbindungsname])
Wie Sie sehen, brauchen wir hier den Namen der Verbindung, den wir unter SQLConnect
definiert
haben.
Nun schicken wir eine Abfrage an die Datenbank. Dies erfolgt durch den Befehl:
SQLPrepare([Statementname, SQL-Statement)
Bei einem negativen Ergebnis konnte das SQL-Statement von MySQL nicht verarbeitet werden. Dies passiert beispielsweise, wenn das SQL-Statement nicht korrekt ist oder die angegebene Tabelle nicht existiert.
SQLPrepare
nimmt folgende Parameter entgegen:
SQLConnect
.)Für den ersten Versuch habe ich nun ein einfaches SQL-Statement ausgesucht. Dieses werden wir vorher in der MySQL-Console ausprobieren. Damit ist sichergestellt, daß uns beim Eingeben des REXX-SQL-Befehls kein SQL-syntaktischer Fehler passiert.
mysql> Select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Oesterreich | +43 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Grossbritannien | +44 | | USA | United State of America | +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | +31 | | L | Luxemburg | +352 | | B | Belgien | +32 | | E | Spanien | +43 | +---------+-------------------------+---------+ 11 rows in set (0.08 sec)
Wie Sie sehen, hat das SQL-Statement funktioniert und wir können es in unser REXX-Programm kopieren. Damit sieht das ganze dann so aus:
if SQLPrepare("prep","Select * from land") < 0 then do say "SQL-Statement hat nicht funktioniert" call SQLDisconnect("conn") end
Um auf das Ergebnis zugreifen zu können, muß es mit Hilfe des Befehls
SQLOPEN(Statementname)
geöffnet werden. Wie schon bei den anderen Funktionen gilt: Ein negatives Ergebnis weist auf einen
aufgetretenen Fehler hin. Tritt dies ein, soll sich das Programm auch hier korrekt von der Datenbank abmelden und
beenden. Das heißt, als erstes muß das Statement, das wir mit SQLOpen
geöffnet haben,
geschlossen werden und dann muß die Verbindung mit SQLDisconnect
beendet werden.
Zum Schließen eines Statements steht folgender Befehl zur Verfügung:
SQLClose(Statement)
Insgesamt sieht das ganze dann so aus:
if sqlopen("prep") < 0 then do say "SQL-Statement hat nicht funktioniert" call SQLClose("prep") call SQLDisconnect("conn") end
Nun lassen wir uns die Eigenschaften des ersten Feldes (»Kurzbez«) anzeigen. Dazu muß folgender Befehl verwendet werden:
SQLDescribe(Statementname [,Info])
Das Array Info
hat dabei folgende Struktur:
NAME |
Name der Spalte |
TYPE |
Datentyp |
SIZE, SCALE , PRECISION |
Größe des Feldes |
NULLABLE ... =1 |
Die Spalte erlaubt den Wert NULL. |
Im Programm sieht dies folgendermaßen aus:
rv=SQLDescribe("prep","desc") say "Name-Anzahl: " desc.column.name.0 say "Name-Bezeichnung:" desc.column.name.1 say "Name-Type: " desc.column.type.1 say "Name-Groesse: " desc.column.size.1 ", " desc.column.precision.1 say "Name-Scale: " desc.column.scale.1 say "Name-Nullable: " desc.column.nullable.1
Mit dem Befehl SQLFetch(Statementname [, zeilenanzahl])
wird das SQL-Ergebnis zeilenweise gelesen,
d.h. jeder Zeile entspricht ein Datensatz. Da wir mehrere Sätze/Zeilen erwarten, müssen wir eine Schleife
verwenden, die bei jedem Durchlauf SQLFetch
aufruft. Da zu einem gewissen Zeitpunkt alle Sätze
gelesen worden sein werden, muß es auch eine Möglichkeit geben, diese Schleife wieder zu verlassen. Diesen
Zeitpunkt zeigt uns SQLFetch
auch an, und zwar durch das Ergebnis 0. Bei einem negativen
Ergebnis ist ein Fehler aufgetreten.
Wie kommt man nun an die einzelnen Felder? Dies ist relativ einfach, wenn man weiß wie es geht. Die
Lösung ist folgende: Bei SQLPrepare
haben wir einen Statementnamen
vergeben.
SQLPrepare
schickt nicht nur das SQL-Statement an die Datenbank, sondern generiert auch eine sogenannte
Stammvariable mit dem Statementnamen
, in unserem Beispiel prep
. Diese Stammvariable hat als
Struktur die Feldnamen des SQL-Statements, in unserem Beispiel also prep.kurzbez, prep.bezeichnung,
prep.vorwahl
. Diese (Stamm-)Variablen lassen wir uns dann mit dem REXX-Befehl SAY
ausgeben.
Dazu müssen wir unserem REXX-Programm folgende Zeilen hinzufügen:
do forever rc = SQLFetch('prep') if rc < 0 then exit 1 if rc = 0 then leave say prep.kurzbez ', ' prep.bezeichnung "," prep.vorwahl end
Zum Schluß müssen noch das Statement und die Verbindung geschlossen werden. Dies geschieht, wie schon
oben beschrieben, mit SQLClose
und SQLDisconnect
.
call SQLClose("prep") call SQLDisconnect("conn") say "Fertig"
Der gesamte Quellcode sieht damit folgendermaßen aus:
/* Programm: ListLand.cmd */ /* Autor: Wolfgang Draxler */ /* Datum: 05.05.2004 */ Call RxFuncAdd "SQLLoadFuncs", "rexxsql", "SQLLoadFuncs" Call SQLLoadFuncs if SQLConnect( "Conn", "root", "<PW>", "adressen", "localhost") < 0 then do say "Verbindungsaufbau hat nicht funktioniert" exit end if SQLPrepare("prep","Select * from land") < 0 then do say "SQL-Statement hat nicht funktioniert" call SQLDisconnect("conn") end if SQLOpen("prep") < 0 then do say "SQL-Statement hat nicht funktioniert" call SQLClose("prep") call SQLDisconnect("conn") end rv=SQLDescribe("prep","desc") say "Name-Anzahl: " desc.column.name.0 say "Name-Bezeichnung:" desc.column.name.1 say "Name-Type: " desc.column.type.1 say "Name-Groesse: " desc.column.size.1 ", " desc.column.precision.1 say "Name-Scale: " desc.column.scale.1 say "Name-Nullable: " desc.column.nullable.1 do forever rc = SQLFetch('prep') if rc < 0 then exit 1 if rc = 0 then leave say prep.kurzbez ', ' prep.bezeichnung "," prep.vorwahl end call SQLClose("prep") call SQLDisconnect("conn") say "Fertig"
Wie Sie sehen, ist es relativ einfach, eine Verbindung zwischen REXX und MySQL aufzubauen.
Nun programmieren wir eine kleine Eingabe für die Tabelle Land. Dazu werden wir eine neue CMD-Datei namens SaveLand.cmd erzeugen.
Als erstes wieder der Kopf und das Einbinden der REXX-MySQL-Funktionen:
/* Programm: SaveLand.cmd */ /* Autor: Wolfgang Draxler */ /* Datum: 05.05.2004 */ Call RxFuncAdd 'SQLLoadFuncs', 'rexxsql', 'SQLLoadFuncs' Call SQLLoadFuncs
Als nächstes fragen wir den User nach Werten für Kurzbez, Bezeichnung und Vorwahl.
Dies geschieht durch den REXX-Befehl Parse Pull
:
Say "Kurzbez:" Parse Pull Kurzbez Say "Bezeichnung:" Parse Pull Bezeichnung Say "Vorwahl:" Parse Pull Vorwahl
Nun werden wir wieder die Verbindung zu der Datenbank aufbauen, wobei Sie »PW« durch Ihr Root-Passwort ersetzen.
if SQLConnect("Conn", "root", "<PW>", "adressen", "localhost") < 0 then do say "Verbindungsaufbau hat nicht funktioniert" exit end
Im nächsten Schritt erstellen wir die Variable »SQL«, die den Insert-Befehl beinhaltet.
SQL = "Insert into land values ('"Kurzbez"','"Bezeichnung"','"Vorwahl"')" say "SQL=" SQL
Diese Variable wird nun an SQLPrepare
übergeben:
if SQLPrepare("prep", SQL) < 0 then do say "SQL-Statement hat nicht funktioniert" call SQLDisconnect("conn") end
Im nächsten Schritt wird die Verbindung geschlossen:
call SQLClose("prep") call SQLDisconnect("conn") say "Fertig"
Zum testen, öffnen wir ein OS/2-Fenster und wechseln in das Verzeichnis, in dem sich die zwei REXX-Programme befinden (beim mir also P:\Rexx\mySQL):
[P:\rexx\mysql]saveland Kurzbez: E Bezeichnung: Spanien Vorwahl: +43 SQL= Insert into land values ('E','Spanien','+43') Fertig
Zur Überprüfung starten wir das erste Programm Listland.cmd:
[P:\rexx\mysql]listland Name-Anzahl: 3 Name-Bezeichnung: bezeichnung Name-Type: CHAR Name-Groesse: 3 , 3 Name-Scale: 0 Name-Nullable: 0 A , Oesterreich , +43 D , Deutschland , +49 CH , Schweiz , +41 GB , Grossbritannien , +44 USA , United State of America , +1 I , Italien , +39 H , Ungarn , +36 NL , Niederlande , +31 L , Luxemburg , +352 B , Belgien , +32 E , Spanien , +43 Fertig
Wie Sie sehen, ist »Spanien« nun auch in der Tabelle. Natürlich können Sie dieses auch mit der MySQL-Console überprüfen.
Jetzt wissen Sie, wie Sie REXX und MySQL verbinden können und ich beende hiermit diese Artikel-Serie.
Weitere Informationen zu den Befehlen finden Sie in der Dokumentation des REXX-Treibers.
Daten und Quellen:
|
Artikelverzeichnis
editor@os2voice.org
< Vorherige Seite | Inhaltsverzeichnis | Nächste Seite >
VOICE-Homepage: http://de.os2voice.org