Forum | | | | Dietmar Horn | Hallo zusammen,
mit meinem XProfan-Firebird-SQL-Projekt klappt es soweit ganz gut.
Nun gibt es aber ein Problem, welches ich möglichst bis vorgestern mit XProfan lösen müßte, falls das mit XProfan aktuell überhaupt möglich ist.
In der ersten offiziellen Beta für ausgesuchte Tester soll das Programm nun unbedingt als Embedded-Variante laufen, und nicht als Nicht-Embedded.
Mit Nicht-Embedded über ODBC-Schnittstelle mittels der normalen FB-SQL-Befehle klappt bisher alles weitestgehend tadellos.
Doch wie kann ich die Embedded-Variante initialisieren, um danach mit denselben SQL-Routinen im Programm wie gewohnt weiterarbeiten zu können? Später soll der Anwender dann zwischen beiden Varianten selber die Auswahl treffen.
Für die SQL-Experten unter euch habe ich schon mal alles in ein ZIP-Archiv gepackt - also Firbird embedded (keine Installation erforderlich) und einige zusätzliche Hilfedateien (außer die, welche im Unterordner doc sowieso schon vorhanden sind). Die beigelegte Patienten.fdb könnte zum Testen dienen.
Selber habe ich die paar laut Hilfedatei(en) benötigten Dateien in das Projektverzeichnis kopiert und auch die fbembed.dll in fbclient.dll umbenannt. Laut Hilfedatei(en) sollte das ausreichen. Wie ich das bis jetzt verstehe, braucht man doch den Rest aus dem Firebird-Ordner aus dem ZIP doch gar nicht unbedingt, oder?
Doch mit KompilierenMarkierenSeparieren bekomme ich einfach keine Verbindung hin!
Wenn ich das in den nächsten Tagen (notfalls eben erst mal per Workarount) nicht irgendwie mit XProfan hinbekomme, dann kann ich die Arbeit von mehreren Monaten im Prinzip in die Tonne kloppen ...
Roland, hast Du vielleicht als Datenbank-Profi eine Lösung für dieses Problem, oder wer von den anderen DB-Profis kennt sich noch damit aus?
Gruß und Danke im voraus!
Dietmar |
| | | Multimedia für Jugendliche und junge Erwachsene - MMJ Hoyerswerda e.V. [...] Windows 95 bis Windows 7 Profan² 6.6 bis XProfan X2 mit XPSE Das große XProfan-Lehrbuch: [...] | 17.04.2009 ▲ |
| |
| | E.T. |
...Die Datenbankdatei muss sich bei der Benutzung des embedded Server neben diesem ebenfalls im Applikationsverzeichnis befinden. ...
Ist mir beim lesen der Anleitung immer wieder aufgefallen. Meist liegen die DB ja in einem anderen Verzeichnis...
[offtopic]...nur so als Gedanke... [/offtopic] |
| | | Grüße aus Sachsen... Mario WinXP, Win7 (64 Bit),Win8(.1),Win10, Win 11, Profan 6 - X4, XPSE, und 'nen schwarzes, blinkendes Dingens, wo ich das alles reinschütte... | 17.04.2009 ▲ |
| |
| | Dietmar Horn | Nein, Mario,
die paar DLLs können im selben Verzeichnis liegen, wie die DB, anderenfalls werden sie von der (umbenannten) fbclient.dll im Windows-, Windows-System- oder Windows-System32-Verzeichnis gesucht. Das haben wir alles stundenlang vergeblich durchprobiert (ähnlich wie damals die Sache mit den BLOBs). Mit ImportDLL(fbclient.dll,*) kann man sich genau ansehen, wo die fbclient.dll die anderen paar DLLs mit den restlichen Funktionen sucht. Notfalls kann man ja mit ChDir in den Ordner wechseln, in dem sich diese paar Dateien tummeln.
Und laut der vielen FB-Hilfedateien stellt in der Embedded-Version die fbclient.dll für das DBMS den eigentlichen Server dar, der alle FB-Funktionalitäten lokal zur Verfügung stellt - aber im Gegensatz zur Nichtembedded-Version muß der Anwender da nicht erst bei jedem noch so kleinen DB-Programm in der Systemsteuerung den ODBC-Treiber konfigurieren.
Meiner Meinung nach fehlt da (bzw. mir) bis jetzt nur noch der allererste Baustein, um diesen Server (also die Embedded-FBClient.dll) zu initialisieren.
Ich vermute bzw. befürchte bald, daß das bis jetzt mit XProfans SQLInit nicht so ohne weiteres möglich sein wird. Ich schätze mal, hier wird wahrscheinlich nur Roland selber zeitnah weiterhelfen können - ähnlich wie bei der BLOB-Geschichte - oder einer von den anderen API-Spezialisten, die sich jetzt schon genauer mit den FB-APIs auskennen, ohne sich selber erst mühsam herantasten zu müssen ... Notfalls eben über eine neue, noch mit C++ oder Delphi zu erstellende FB-Embedded-DLL für XProfan. Meine nächste Befürchtung geht dahin, daß SQL-Exec ebenfalls den installierten ODBC-Treiber voraussetzt und man das ganze SQL-Zeugs mit SQLExec dann ebenfalls api-mäßig selber nachbasteln müßte. Hoffentlich habe ich mit meinen Berfürchtungen nicht recht, denn dann wäre ohne Rolands rasche Hilfe mein aktuelles schon recht weit fortgeschrittenes Projekt nur aus diesen Gründen zum Scheitern verurteilt und monatelange Programmierarbeit für die Katz gewesen.
Ich würde mich jedoch riesig darüber freuen, wenn ich in diesen Punkten Denkfehler begehe und ich mal wieder nur den Wald vor lauter Bäumen nicht sehe. Doch wie im Ausgangsposting bereits gesagt: Die Zeit hängt mir wegen dieser Geschichte inzwischen ganz schön im Nacken.
Gruß Dietmar |
| | | Multimedia für Jugendliche und junge Erwachsene - MMJ Hoyerswerda e.V. [...] Windows 95 bis Windows 7 Profan² 6.6 bis XProfan X2 mit XPSE Das große XProfan-Lehrbuch: [...] | 18.04.2009 ▲ |
| |
| | RGH | Hallo,
auch wenn ich heute keine Zeit habe, ein erster Hinweis: Ohne ODBC-Treiber wird es natürlich nicht gehen: Ohne ODBC-Treiber kann die ODBC-Schnittstelle von XProfan natürlich nicht funktionieren. Gibt es einen ODBC-Treiber für Firebird-Emedded? Oder lässt sich der bisherige Treiber für Embedded konfigurieren?
Direkter Aufruf über die API der DLL könnte natürlich gehen. Ist diese irgendwo dokumentiert? Vermutlich gibt es da eine Dokumentation für Delphi oder C++ ... oder im schlimmsten Fall nur fertige Komponenten ohne Quellcode, die über ihre Zugriffe nichts preis geben. (Allerdings wären die bisherigen Überlegungen dann tatsächlich ziemlich wertlos, da es dann ja um etwas ganz Anderes geht. Das hätte man von Anfang an erwähnen müssen. Ok, die Oberfläche kann natürlich bleiben ...)
Gruß Roland |
| | | Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 19.04.2009 ▲ |
| |
| | | Vielleicht mal den Florian Heuberger fragen ob er mit Visual-Zeugs auf sowas Zugriff hat. |
| | | | |
| | Dietmar Horn | Hallo,
nein, das ist ja der Sinn von FB-Embedded, daß man da keinen ODBC-Treiber benötigt. Mehreren andere Programmen aus dieser Branche machen das genauso. Der Anwender kann optional umschalten, welchen Modus er nutzen möchte: Embedded (local, ohne gleichzeitigen Mehrfachzugriff), oder Nicht-Embedded (Mehrfachzugriff auf DB über Netzwerk möglich).
An Dokumentationen habe ich das, was bei FB sowieso dabei ist, das was ich mit in das obige ZIP gepackt habe und noch ein API-Guide für Interbase (IB und FB sollen wohl kompatibel sein) - siehe Anhang. Für mich ein Buch mit sieben Siegeln!
Allerdings wären die bisherigen Überlegungen dann tatsächlich ziemlich wertlos, da es dann ja um etwas ganz Anderes geht.
Wertlos nicht, denn ich benötige zwingend beide Modi. Nur dumm, daß der Projektleiter die Beta-Version ausgewählten Testern nun vorerst als Embedded geben möchte (weil diese zu 99% nicht in der Lage sind, sich die ODBC-Geschichte selber einzurichten).
Den normalen Modus habe ich fertig, da funktioniert dbzgl. mit XProfan bis jetzt alles bestens.
Gruß Dietmar |
| | | Multimedia für Jugendliche und junge Erwachsene - MMJ Hoyerswerda e.V. [...] Windows 95 bis Windows 7 Profan² 6.6 bis XProfan X2 mit XPSE Das große XProfan-Lehrbuch: [...] | 19.04.2009 ▲ |
| |
| | RGH | Hallo,
wie gesagt, für die in XProfan integrierten ODBC-Funktionen ist ein ODBC-Treiber zwingende Vorraussetzung. Dieses Umschalten auf Embedded ohne ODBC funktioniert also nur für Anwendungen, die generisch, also direkt per Firebird- bzw. Interbase-API, mit der Datenbank kommunizieren. Für Delphi oder C++ werden vermutlich entsprechende Komponenten mitgeliefert. Bei diesen Anwendungen wird also von vornherein nicht der Umweg über ODBC gegangen. Der Zugriff auf die Datenbank ist also ein ganz anderer und da sind die bisherigen Überlegungen zum Speichern und Lesen von BLOBs über ODBC tatsächlich kaum verwendbar.
Möglicherweise braucht man aber keine extra zu schreibende DLL, sondern kann die API direkt verwenden.
Gruß Roland |
| | | Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 19.04.2009 ▲ |
| |
| | RGH | Hallo, ich habe mal einen kurzen Blick auf den API-Guide geworfen. Da scheint ja alles drin zu stehen, was man braucht: isc_attach_database() zum Öffnen der Datenbank, isc_dsql_exec_immediate() zum Ausführen eines SQL-Statements, etc. Die API erinnert ein wenig an die ODBC-API. Ich schaue mal, dass ich die nächsten Tage Zeit finde, damit ein wenig zu experimentieren. (Aber es ich hindere auch niemanden, es selbst zu probieren. Die Beschreibungen scheinen mir recht ausführlich zu sein.)
Gruß Roland |
| | | Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 19.04.2009 ▲ |
| |
| | Dietmar Horn | Hallo Roland,
danke im voraus für Deine Mühe!
Wenn dieser Embedded-Modus irgendwie klappt, dann bin ich fix und fertig und werde bestimmt reif für die Klappse sein! Das wäre dann vielleicht aber auch nicht schlecht, denn dort hätte ich vermutlich genügend Zeit, mein XProfan-Lehrbuch um zwei weitere größere Kapitel zu ergänzen:
XProfan und die relationalen Datenbanksysteme Firebird und Interbase
1. Meine armen Nerven und Firebird 2. Einführung in Firebird mit XProfan
Weil Firebird ja kostenlos zu haben ist, wäre das dann eine clevere Nicht-ODBC-Alternative zu dem z.T. doch recht eingeschränkten und in die Jahre gekommenen dBase.
Gruß Dietmar |
| | | Multimedia für Jugendliche und junge Erwachsene - MMJ Hoyerswerda e.V. [...] Windows 95 bis Windows 7 Profan² 6.6 bis XProfan X2 mit XPSE Das große XProfan-Lehrbuch: [...] | 20.04.2009 ▲ |
| |
| | RGH | Hallo,
hier ein erster Teil zur Verwendung von direktem Zugriff auf Firebird mittels XProfan. Das Beispiel sollte sowohl für die Client-Version (da heißt die DLL allerdings anders: fbclient.dll, bei Interbase natürlich auch) als auch wie hier für die Embedded-Version funktionieren.
ACHTUNG: Das Beispiel funktioniert! Wenn man mit Ja antwortet wird die Datenbank tatsächlich gelöscht und beim Versuch, die nicht mehr vorhandene Datenbank zu schließen, gibt es die entsprechene Firebird-Fehlermeldung. ALso vorher bitte eine Sicherheitskopie der Datenbankdatei (im Beispiel Patienten.fdb) erstellen.
Was geschieht im Programm? - Mit ImportDLL werden die API-Funktionen der DLL imortiert - Mit isc_expand_dpb() wird der Verbindungsstring erzeugt. In unserem Fall brauchen wir nur Username und Paßwort. Die entsprechenden Konstanten kommen aus der ibase.h - Mit isc_attach_database() wird die Verbindung zur Datenbank hergestellt. Wenn der erste Eintrag des Status-Arrays eine 1 ist, ist der zweite Eintrag im Falle ungleich 0 die Interbase-Fehlernummer. In diesem Fall wird mit isc_interprete() der text der entsprechenden Fehlermeldung ermittelt. - mit isc_drop_database() können wir nun die Datenbank löschen. Das klappt natürlich nur mit korrektem Usernamen und Paßwort. Ansonsten gibt es eine Fehlermeldung. (Das Löschen der Datenbank habe ich als praktischen Test für die erfolgreiche Verbindung gewählt, weil ein SELECT ein wenig komplexer wäre ... ;) ) Mit etwas Fleiß und Erfahrung kann man natürlich mit den übrigen API-Funktionen auch SQL-Statements absetzen, BLOBs schreiben und lesen, etc. Die API erinnert ein wenig an die ODBC-API ... leider nur ein wenig. - Mit isc_detach_database() wird die Verbindung zur Datenbank beendet ... vorrausgesetzt sie wurde im vorigen Schritt nicht gelöscht.
Das Beispiel beweist, was aber eh klar war: Wenn mit anderen Programmiersprachen der direkte Zugriff auf Firebird geht, geht es auch mit XProfan: KompilierenMarkierenSeparierenFireBird Embedded Demo
----------------------
©2009 Roland G. Hülsmann
Definitionen aus ibase.h
def &isc_dpb_user_name 28
def &isc_dpb_password 29
declare msg#
declare status_vector&[20]
declare pdpb&, pstatus&
var hdll& = ImportDLL(fbembed.dll, fb_)
dim msg#, 512
var dpb_length& = 0 Länge des Verbindungsstrings
var db1& = 0 Databasehandle
var user$ = SYSDBA
var pass$ = masterkey
var name$ = Patienten.fdb
cls
Verbindungsstring erstellen
fb_isc_expand_dpb(addr(pdpb&), addr(dpb_length&),
&isc_dpb_user_name, addr(user$),
&isc_dpb_password, addr(pass$),
0)
whileloop 0, dpb_length& - 1
print hex$(byte(pdpb&,&loop));,;
endwhile
Verbindung zur Datenbank herstellen und auf Fehler prüfen
fb_isc_attach_database(addr(status_vector&[0]), len(name$), addr(name$), addr(db1&), dpb_length&, pdpb&)
if ((status_vector&[0] = 1) and status_vector&[1])
pstatus& = addr(status_vector&[0])
fb_isc_interprete(msg#, addr(pstatus&))
messagebox(string$(msg#, 0), Firebird-Fehler, 16)
end 1
endif
Hier könnte nun der Zugriff auf die Datenbank stattfinden ...
Im Beispiel wird die Datenbank gelöscht! (Vor dem Ausprobieren bitte Sicherheitskopie anlegen!)
if messageBox(Wollen Sie die Datenbank wirklich löschen?, Frage:, 36) = 6
fb_isc_drop_database(addr(status_vector&[0]), addr(db1&))
if ((status_vector&[0] = 1) and status_vector&[1])
pstatus& = addr(status_vector&[0])
fb_isc_interprete(msg#, addr(pstatus&))
messagebox(string$(msg#, 0), Firebird-Fehler, 16)
end 2
endif
endif
Verbindung mit der Datenbank lösen und auf Fehler prüfen
fb_isc_detach_database(addr(status_vector&[0]), addr(db1&))
if ((status_vector&[0] = 1) and status_vector&[1])
pstatus& = addr(status_vector&[0])
fb_isc_interprete(msg#, addr(pstatus&))
messagebox(string$(msg#, 0), Firebird-Fehler, 16)
end 3
endif
end
Gruß Roland |
| | | Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 20.04.2009 ▲ |
| |
| | Dietmar Horn | Danke!
Das SQLInit und SQLDone hätten wir dann ja schon mal.
Wenn ich dann noch irgendwie das Äquivalent zu SQLExec per API mit den ganz normalen SQL-Übergabestrings (SELECT, INTO, UPDATE, etc.) hätte, dann wäre die Kuh ja erst mal fast vom Eis.
Gruß Dietmar |
| | | Multimedia für Jugendliche und junge Erwachsene - MMJ Hoyerswerda e.V. [...] Windows 95 bis Windows 7 Profan² 6.6 bis XProfan X2 mit XPSE Das große XProfan-Lehrbuch: [...] | 20.04.2009 ▲ |
| |
| | RGH | Dietmar Horn, Beitrag=51895, Zeitpunkt=20.04.2009
Danke!
Das SQLInit und SQLDone hätten wir dann ja schon mal.
Wenn ich dann noch irgendwie das Äquivalent zu SQLExec per API mit den ganz normalen SQL-Übergabestrings (SELECT, INTO, UPDATE, etc.) hätte, dann wäre die Kuh ja erst mal fast vom Eis.
Gruß Dietmar
Nun denn! Das meiste geht schon. Aus Gründen, die mir noch nicht bekannt sind, läßt sich kein Feld mit NUMERIC(10,2) definieren. NUMERIC(8,2) hingegen funktioniert. Und Felder, die mit NUMERIC(10,2) definiert sind, wie z.B. SALARY in EMPLOYEES erzeugen beim Zugriff lediglich eine Fehlermeldung. Und BLOBs gibt es auch noch nicht, dürften aber kein großes Problem sein. KompilierenMarkierenSeparierenFireBird Embedded Demo
----------------------
©2009 Roland G. Hülsmann
Definitionen aus ibase.h
def &isc_dpb_user_name 28
def &isc_dpb_password 29
def &SQLDA_VERSION1 1
def &DSQL_close 1
def &DSQL_drop 2
def &SQL_TEXT 452
def &SQL_VARYING 448
def &SQL_SHORT 500
def &SQL_LONG 496
def &SQL_FLOAT 482
def &SQL_DOUBLE 480
def &SQL_D_FLOAT 530
def &SQL_TIMESTAMP 510
def &SQL_BLOB 520
def &SQL_ARRAY 540
def &SQL_QUAD 550
def &SQL_TYPE_TIME 560
def &SQL_TYPE_DATE 570
def &SQL_INT64 580
Weitere Definitionen
def &varchar $1C0 448 SQL_VARYING NOT NULL
def &varchar2 $1C1 449 NULL ALLOWED
def &char $1C4 452 SQL_TEXT NOT NULL
def &char2 $1C5 453 NULL ALLOWED
def &float $1E2 482 SQL_FLOAT NOT NULL
def &float2 $1E3 NULL ALLOWED
def &long $1F0 496 SQL_LONG NOT NULL
def &long2 $1F1 497 NULL ALLOWED
def &short $1F4 500 SQL_SHORT NOT NULL
def &short2 $1F5 501 NULL ALLOWED
def &date $1FE 510 SQL_TIMESTAMP N NULL
def &date2 $1FF 511 NULL ALLOWED
def &blob $208 520 SQL_BLOB NOT NULL
def &blob2 $209 521 NULL ALLOWED
Strukturen aus ibase.h
struct XSQLVAR =
sqltype%, 00:datatype of field
sqlscale%, 02:scale factor
sqlsubtype%, 04:datatype subtype - BLOBs & Text types only
sqllen%, 06:length of data area
sqldata&, 08:address of data
sqlind&, 12:address of indicator variable (short)
sqlname_length%, 16:length of sqlname field
sqlname$(31), 18:name of field, name length + space for NULL
relname_length%, 50:length of relation name
relname$(31), 52:fields relation name + space for NULL
ownname_length%, 84:length of owner name
ownname$(31), 86:relations owner name + space for NULL
aliasname_length%, 118:length of alias name
aliasname$(31) 120:relations alias name + space for NULL -> 151 = 152 Bytes
struct XSQLDA =
version%, 00:version of this XSQLDA
sqldaid#(14), 02:for future use
sqln%, 16:number of fields allocated
sqld% 18:actual number of fields
Weitere Strukturen
struct TIMEDATE =
sek&, 0 .. 59
min&, 0 .. 59
std&, 0 .. 23
tag&, 1 .. 31
mon&, 0 .. 11 !
jahr&, Jahr - 1900 (109 = 2009)
wtag&, Wochentag 0 .. 6, 0 = Sonntag
jtag&, Tag im Jahr 0 .. 365
isdst& Ungleich null bei US-Sommerzeitkonvertierung
Funktionen aus DLL importieren
var hdll& = ImportDLL(fbembed.dll, fb_)
proc fbError
parameters sv&[]
declare msg#
dim msg#, 512
var pstatus& = addr(sv&[0])
var sqlcode& = fb_isc_sqlcode(addr(sv&[0]))
if sqlcode& < 0 SQL-Fehlergefunden
fb_isc_sql_interprete(sqlcode&, msg#, 512)
else
fb_isc_interprete(msg#, addr(pstatus&))
endif
if get(errorlevel) > 0
messagebox(string$(msg#, 0), Firebird Fehler:, 16)
end 1
elseif get(errorlevel) = 0
messagebox(string$(msg#, 0), Firebird Warnung:, 16)
endif
endproc
proc fbInit
parameters user$, pass$, name$
declare status_vector&[20]
var dpb_length& = 0 Länge des Verbindungsstrings
var db1& = 0 Databasehandle
var pdpb& = 0 Zeiger auf Verbindungsstring
Verbindungsstring erstellen
fb_isc_expand_dpb(addr(pdpb&), addr(dpb_length&),
&isc_dpb_user_name, addr(user$),
&isc_dpb_password, addr(pass$),
0)
Verbindung zur Datenbank herstellen und auf Fehler prüfen
fb_isc_attach_database(addr(status_vector&[0]), len(name$), addr(name$), addr(db1&), dpb_length&, pdpb&)
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
return db1&
endproc
proc fbDone
parameters db1&
declare status_vector&[20]
Verbindung mit der Datenbank lösen und auf Fehler prüfen
fb_isc_detach_database(addr(status_vector&[0]), addr(db1&))
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
endproc
proc fbDrop
parameters db1&
declare status_vector&[20]
fb_isc_drop_database(addr(status_vector&[0]), addr(db1&))
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
endproc
proc pad
parameters s$, l&
return left$(s$ + space$(l&), l&)
endproc
proc fbSQLExec
parameters db1&, sql$, mode%
declare status_vector&[20], trans&, stmt&
declare osqlda#, osqlvar#, osql#, tm_date#
var sqlcount& = 0
dim osqlda#, XSQLDA
dim osqlvar#, XSQLVAR
dim tm_date#, TIMEDATE
Transaktion starten
fb_isc_start_transaction(addr(status_vector&[0]), addr(trans&), 1, addr(db1&), 0, 0)
if trans& > 0
Statementhandle holen
if left$(upper$(trim$(sql$)),7) <> SELECT
fb_isc_dsql_execute_immediate(addr(status_vector&[0]), addr(db1&), addr(trans&), len(sql$), addr(sql$), 1, 0)
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
else
fb_isc_dsql_allocate_statement(addr(status_vector&[0]), addr(db1&), addr(stmt&))
if stmt& > 0
Datenbereich zunächst für das Lesen der ersten 2 Felder vorbereiten
dim osql#, sizeof(osqlda#) + 2 * sizeof(osqlvar#)
clear osql#
osqlda# = addr(osql#)
osqlda#.version% = &SQLDA_VERSION1
osqlda#.sqln% = 2
Informationen über erste 2 Felder holen (Datentyp, Länge, etc.)
fb_isc_dsql_prepare(addr(status_vector&[0]), addr(trans&), addr(stmt&), len(sql$), addr(sql$), 1, osql#)
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
var d% = osqlda#.sqld%
if d% > 2
Wenn mehr als zwei Felder, dann Datenbereich für erittelte Feldanzahl neu dimensionieren
clear osql#
dim osql#, sizeof(osqlda#) + d% * sizeof(osqlvar#)
osqlda# = addr(osql#)
osqlda#.version% = &SQLDA_VERSION1
osqlda#.sqln% = d%
Informationen über alle Felder holen (Datentyp, Länge, etc.)
fb_isc_dsql_prepare(addr(status_vector&[0]), addr(trans&), addr(stmt&), len(sql$), addr(sql$), 1, osql#)
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
endif
Feldbeschreibungen füllen und Titelzeile erzteugen
declare fname$[d%-1], ftyp%[d%-1], fstyp%[d%-1], flen%[d%-1], fscale%[d%-1], fdata$[d%-1]
var zeile$ =
var maxlen& = 0
whileloop 0, d%-1
osqlvar# = addr(osql#) + sizeof(osqlda#) + &loop * sizeof(osqlvar#)
fname$[&loop] = osqlvar#.sqlname$
flen%[&loop] = osqlvar#.sqllen%
case len(fname$[&loop]) > flen%[&loop] : flen%[&loop] = len(fname$[&loop])
ftyp%[&loop] = osqlvar#.sqltype%
fstyp%[&loop] = osqlvar#.sqlsubtype%
case ftyp%[&loop] = &date : flen%[&loop] = 10
case ftyp%[&loop] = &date2 : flen%[&loop] = 10
fscale%[&loop] = osqlvar#.sqlscale%
print osqlvar#.sqltype%, hex$(ftyp%[&loop]),fstyp%[&loop],fname$[&loop],flen%[&loop]
zeile$ = zeile$ + pad(fname$[&loop],flen%[&loop]) + |
case flen%[&loop] > maxlen& : maxlen& = flen%[&loop]
endwhile
Titelzeile ausgeben
select mode%
caseof 0 : print zeile$
caseof 1 : addstring zeile$
endselect
Trennlinie erzeugen und ausgeben
zeile$ =
whileloop 0, d%-1
zeile$ = zeile$ + mkstr$(-,flen%[&loop]) + |
endwhile
select mode%
caseof 0 : print zeile$
caseof 1 : addstring zeile$
endselect
Statement ausführen
fb_isc_dsql_execute(addr(status_vector&[0]), addr(trans&), addr(stmt&), 1, 0)
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
Datenbereich für Empfang eines Satzes vorbereiten
osqlda#.sqln% = d% * 256
declare data#[d%-1]
declare ind&[d%-1]
dim data#[], maxlen& + 1
whileloop 0, d% - 1
long osql#, sizeof(osqlda#) + &loop * sizeof(osqlvar#) + 8 = addr(data#[&loop])
long osql#, sizeof(osqlda#) + &loop * sizeof(osqlvar#) + 12 = addr(ind&[&loop])
endwhile
Daten satzweise holen und auswerten
var retcode& = 0
retcode& = fb_isc_dsql_fetch(addr(status_vector&[0]), addr(stmt&), 1, osql#)
while retcode& <> 100 100: keine weiteren Sätze
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
zeile$ =
whileloop 0, d%-1
select ftyp%[&loop]
caseof &varchar, &varchar2
fdata$[&loop] = string$(data#[&loop],2)
caseof &date, &date2
fb_isc_decode_sql_date(data#[&loop],tm_date#)
fdata$[&loop] = dtoc$(format$(%.4d, tm_date#.jahr& + 1900)
+ format$(%.2u, tm_date#.mon& + 1)
+ format$(%.2u, tm_date#.tag&))
caseof &char, &char2
fdata$[&loop] = string$(data#[&loop],0)
caseof &long, &long2, &short, &short2
fdata$[&loop] = str$(long(data#[&loop],0))
caseof &float, &float2
fdata$[&loop] = str$(double(long(data#[&loop],0)))
caseof &blob, &blob2
fdata$[&loop] = BLOB- + str$(fstyp%[&loop])
endselect
zeile$ = zeile$ + pad(fdata$[&loop],flen%[&loop]) + |
endwhile
inc sqlcount&
Datenzeile ausgeben
select mode%
caseof 0 : print zeile$
caseof 1 : addstring zeile$
endselect
retcode& = fb_isc_dsql_fetch(addr(status_vector&[0]), addr(stmt&), 1, osql#)
endwhile
endif
Statementhandle freigeben
fb_isc_dsql_free_statement(addr(status_vector&[0]), addr(stmt&), &DSQL_drop)
endif SELECT-Ende
Transaktion abschließen
fb_isc_commit_transaction(addr(status_vector&[0]), addr(trans&))
endif
if ((status_vector&[0] = 1) and status_vector&[1])
fbError(status_vector&[])
endif
return sqlcount&
endproc
=============
HAUPTPROGRAMM
=============
window 1000, 800
cls
var db1& = fbInit(SYSDBA, masterkey, Employee.fdb)
set(errorlevel, -1)
fbSQLExec(db1&, drop table BUECHER, 1)
set(errorlevel, 1)
fbSQLExec(db1&, create table BUECHER (titel CHAR(40), autor CHAR(40), preis NUMERIC(8,2), datum TIMESTAMP), 1)
fbSQLExec(db1&, INSERT INTO buecher (titel,autor,preis) VALUES (XProfan für Dummies,RGH-Soft,19.94), 1)
clearlist
fbSQLExec(db1&, select * from BUECHER, 1)
listbox$(BUECHER:,2)
clearlist
print fbSQLExec(db1&, select EMP_NO, FIRST_NAME, LAST_NAME, JOB_CODE, JOB_GRADE, JOB_COUNTRY, FULL_NAME, PHONE_EXT, HIRE_DATE from EMPLOYEE, 1)
listbox$(EMPLOYEE:,2)
clearlist
print fbSQLExec(db1&, select * from PROJECT, 1)
listbox$(PROJECT:,2)
clearlist
print fbSQLExec(db1&, select * from CUSTOMER, 1)
listbox$(CUSTOMER:,2)
waitinput
fbDone(db1&)
end
|
| | | Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 22.04.2009 ▲ |
| |
|
AntwortenThemenoptionen | 7.166 Betrachtungen |
ThemeninformationenDieses Thema hat 5 Teilnehmer: |