Deutsch
Forum

SQL, Firebird / Interbase und XProfan

 
- Seite 1 -



Dietmar
Horn
Hallo zusammen,

heute wende ich mich mal mit einem SQL-Problem zwecks Bitte um Hilfestellung an die SQL-Experten unter euch.

Ich arbeite z.Z. mit XProfan 11 an einem komplexeren Projekt. Es ist schon recht weit gediehen. Der bisher einzigste, aber entscheidende Problempunkt ist für mich die An- bzw. Einbindung des RDBS Firebird (Freeware bzw. Open-Source) bzw. Interbase (das kostenpflichtige Gegenstück von Borland zu Firebird - ähnlich wie das Verhältnis zwischen MS Office und Open-Office).

Bisher mußte ich mich noch nie groß mit SQL beschäftigen, außer daß ich mir immer mal die XProfan-Hilfe zum SQL-Thema reingezogen und das alles als recht logisch empfunden hatte. Doch wie des öfteren, liegt der Hund bestimmt nur in einem winzigen Detail begraben, was ich nicht kenne, oder in einem Fehler, den ich gemacht oder übersehen habe.

Firebird und Interbase kannte ich bis vor 4 Wochen noch nicht mal vom Namen her, weil ich sowas noch nie benötigt hatte - aber nun ist es soweit.

ODBC-Treiber und Firebird sind installiert.

Zunächst geht es darum, eine Verbindung herzustellen. Unter Windows 2000 (in unserem Vereins-Kabinett) klappt die Initialisierung mit SQLInit inzwischen.

Die Initialisierung liefert unter W 2000 wie gewünscht das Handle zurück:
var i% = SQLINIT(DSN=Firebird;)
messagebox(str$(i%),,4160)

Unter Windows XP ergibt das jedoch bis jetzt immer 0 (also gescheitert), und im Gegensatz zu W 2000 erscheint da vorher noch nicht mal der Dialog zum Eingeben von Username, PWD, usw.

Bevor dieses Problem mit dem Herstellen der Verbindung nicht gelöst ist, brauche ich gar nicht groß weitermachen.

Literatur über Firebird habe ich inzwischen tonnenweise, doch bevor ich es nicht schaffe, auf allen Windows-Systemen ab 2000 aufwärts eine zuverlässige Verbindung herzustellen, nützt mir das alles leider nicht allzu viel.

Kann mir vielleicht jemand weiterhelfen, der sich schon mal etwas näher damit beschäftigt hat?

Die nächsten Schritte, also das Neuanlegen einer Datenbank, oder das Bearbeiten / Auslesen einer vorhandenen DB und das Weiterverarbeiten der Daten im eigentlichen Programm dürfte dann lediglich noch einer reine Fleiß- und Logik-Arbeit sein.

Das Ausweichen z.B. auf dBase ist nicht möglich, weil dBase dbzgl. nicht über die für dieses Projekt erforderlichen Feautures verfügt.

Wer kann evtl. weiterhelfen?

Ich vermute mal, wenn das Programm irgendwann mit Firebird läuft, dann müßte das Programm auch mit Interbase funktionieren - oder?

Gruß und Danke im voraus
Dietmar

111 kB
Hochgeladen:11.01.2009
Ladeanzahl208
Herunterladen
33 kB
Hochgeladen:11.01.2009
Ladeanzahl171
Herunterladen
 
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:  [...] 
11.01.2009  
 



 
- Seite 5 -



Uwe
''Pascal''
Niemeier
Hi Leute!

Die interne Struktur der db kann euch doch egal sein; dafür gibt es ja den Treiber

Also nochmal: Wo genau liegt das Problem, wann und unter welchen Umständen tritt es auf?
Solche Aussagen wie Das klappt nicht  oder Da kommt nur Müll raus  sind nicht sehr aussagekräftig und für Ferndiagnosen definitiv ungeeignet

Vorschlag: Poste doch mal einer eine Kurzanleitung, was man wo runterladen & wie installieren muß, um eure Versuche nachzuvollziehen.

SeeYou
Pascal
 
24.02.2009  
 




RGH
Hallo Pascal,

ich denke, das Problem besteht einfach darin, dass es offensichtlich keine Möglichkeit (oder Dokumentation derselben) gibt, wie ich mit SQL-Befehlen (SQLExec) über ODBC auf die BLOBs von Interbase/Firebird-Datenbanken zugreifen kann.

Wie es einfach möglich ist, über einen kleinen Umweg große Dateien in Interbase/Firebird zu schreiben und zu lesen, habe ich im Beispiel oben demonstriert. (Das würde sogar leicht abgewandelt mit dBase und anderen funktionieren.) Dietmar hat aber wohl von seinem Auftraggeber die Anforderung, tatsächlich BLOBs zu lesen und zu schreiben.

Firebird und die ODBC-Treiber findest Du hier [...]  im Downloadbereich. Eine Beispieldatenbank findest Du in diesem Thread weiter oben.

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
24.02.2009  
 




Uwe
''Pascal''
Niemeier
*räusper*

Also... Das Problem liegt anscheinend darin, daß der Kommandostring nicht länger als 64KB sein darf. Wird diese Grenze überschritten, kommt es zu Fehlermeldungen, wobei die Meldungen selbst von der Überlänge abhängen. Sieht nach einem Buffer-Überlauf aus; möglicherweise ein Bug im Treiber, den noch keiner bemerkt hat, weil die meisten Programmierer mit den jeweiligen Komponenten für ihre Programmiersprache arbeiten (Weicheier ).

Ein Workaround wäre, überlange Daten nicht auf einmal in die db zu schreiben, sondern stückweise. Allerdings nicht wie in Rolands Beispiel auf mehrere Datensätze verteilt sondern immer ins gleiche Feld des gleichen Satzes, wobei die neuen Daten an die bereits vorhandenen angehängt werden. Zur Verbindung von Strings wird dabei bei FB ein doppeltes Pipe-Zeichen verwendet.

Bei diesem Beispiel werden in mehreren Schritten 128 KB geschrieben:
KompilierenMarkierenSeparieren
window 50,50-500,500
declare Exec$
var GDB$=C:2TestKURSDB.GDB------------Pfad anpassen!!
var Init$=Driver=Firebird/InterBase(r) driver;Uid=SYSDBA;Pwd=masterkey;DbName=+GDB$+;
SQLInit(Init$)
Set(Errorlevel,0)
Exec$=DROP TABLE TCS
SQLExec Exec$,0
Set(Errorlevel,1)
Exec$=CREATE TABLE TCS (Feld1 BLOB)
SQLExec Exec$,0
var Text$=mkstr$(X,1024*32)--Teststring 32KB
Exec$=INSERT INTO TCS (Feld1) VALUES (+Text$+)-------------------32K
SQLExec Exec$,0
Exec$=UPDATE TCS SET Feld1 = (SELECT Feld1 FROM TCS) || +Text$+--32KB + 32KB
SQLExec Exec$,0
Exec$=UPDATE TCS SET Feld1 = (SELECT Feld1 FROM TCS) || +Text$+--64KB + 32KB
SQLExec Exec$,0
Exec$=UPDATE TCS SET Feld1 = (SELECT Feld1 FROM TCS) || +Text$+--96KB + 32KB
SQLExec Exec$,0
Exec$=UPDATE TCS SET Feld1 = Hallo Leute! || (SELECT Feld1 FROM TCS) || Wie siehts aus?
SQLExec Exec$,0
SQLDone
waitkey

Wenn man nun den Blob mit Standart-Funktionen auslesen will, kriegt man nur die interne Blob-ID zurück.
Anders mit der SQL-API-Variante:
KompilierenMarkierenSeparieren
window 50,50-500,500
 $H Windows.ph
def SQLAllocHandle(3) !odbc32,SQLAllocHandle
def SQLError(8 ) !odbc32,SQLError
def SQLExecDirect(3) !odbc32,SQLExecDirect
def SQLGetData(6) !odbc32,SQLGetData
def SQLFetch(1) !odbc32,SQLFetch
def SQLFreeHandle(2) !odbc32,SQLFreeHandle

proc SQLErrorLog-----------------------------------------SQLErrorLog

    parameters Von$
    declare Error$
    SQLError(&SQLEnv,&SQLDBC,stmt&,0,0,Error#,512,0)
    Error$=string$(Error#,0)
    case len(Error$):addstring Von$+ : +Error$
    endproc-------------------------------------------------------------

    proc SQLGetDataEx---------------------------------------SQLGetDataEx

        parameters Exec$
        declare Data#,Data$,Size&,stmt&,Error#
        dim Error#,512
        clearlist
        SQLAllocHandle(3,&SQLDBC,addr(stmt&))--3=SQL_HANDLE_STMT
        SQLErrorLog(SQLAllocHandle)
        SQLExecDirect(stmt&,addr(Exec$),-3)-- -3=SQL_NTS
        SQLErrorLog(SQLExecDirect)
        dim Data#,1--Dummy-DIM
        SQLFetch(stmt&)
        SQLErrorLog(SQLFetch)
        SQLGetData(stmt&,1,99,Data#,0,addr(Size&))--99=SQL_C_DEFAULT
        --Fehlerabfrage würde zu kleinen Puffer melden (Dummy-Aufruf wg. Size&)

        if Size&>0

            dim Data#,Size&+1
            SQLGetData(stmt&,1,99,Data#,Size&+1,addr(Size&))--99=SQL_C_DEFAULT
            SQLErrorLog(SQLGetData)
            Data$=char$(Data#,0,Size&)

        endif

        SQLFreeHandle(3,stmt&)--3=SQL_HANDLE_STMT
        dispose Data#,Error#
        case %getcount>-1:listbox$(Fehler,2)
        return Data$
        endproc-------------------------------------------------------------
        var GDB$=C:2TestKURSDB.GDB--------------Pfad anpassen!!
        var Init$=Driver=Firebird/InterBase(r) driver;Uid=SYSDBA;Pwd=masterkey;DbName=+GDB$+;
        SQLInit(Init$)
        var Exec$=SELECT Feld1 FROM TCS
        var Text$=SQLGetDataEx(Exec$)
        print Gelesene KB:,len(Text$)/1024
        print Erste 20   :,left$(Text$,20)
        print Letzte 20  :,right$(Text$,20)
        SQLDone
        waitkey

Wies mit binären Daten aussieht weiß ich noch nicht, aber ich vermute, daß man ums Kodieren nicht herumkommt, weil ja zumindest das Hochkomma in jedem Fall vom Treiber falsch verstanden werden würde.

HTH
Pascal
 
24.02.2009  
 




RGH
Hallo Pascal und Dietmar,

ich habe gestern Abend etwas Zeit gehabt und mal etwas weiter zum Thema geforscht:

Zum Schreiben von BLOBs:
Hier liegt die Grenze tatsächlich bei der SQL-Implementierung von Firebird/Interbase: In der Doku wird tatsächlich erwähnt, dass die maximale Länge eines SQL-Statements 64 kB nicht überschreiben darf. Für Text-BLOBs ist also Pasacals Lösungsweg durchaus gangbar. Ich habe bislang allerdings keine SQL-Syntax für Firebird/Interbase gefunden, um größere Daten oder gar binäre Daten direkt per SQL in die Tabelle einzufügen.
Andere Datenbanken bieten da z.B. eine Möglichkeit komplette Dateien einzufügen:
KompilierenMarkierenSeparieren
Es wäre hilfreich, wenn es dergleichen auch für Firebird/Interbase gäbe. Ich werde heute Abend weiter forschen ...

Zum Auslesen von BLOBs:
Pascal, als ich Deinen Code sah dachte ich als Erstes: Aber genau so mache ich es doch auch in XProfan. Beim näheren Studium meiner Quellcodes fiel mir dann auf, dass eine von mir genutzte Definitionsdatei zur ODBC32.DLL (Ich benutze die ODBC.DLL Interface Unit, translated for Delphi Yasser Asmi) einen winzigen Fehler enthält. Es fehlt an einer Stelle ein Minuszeichen und zwar wird die Konstante SQL_LONGVARBINARY mit 4, statt mit -4 definiert. Die 4 steht aber für SQL_INTEGER. Dummerweise hat unser BLOB genau den Datentyp SQL_LONGVARBINARY, so dass also aufgrund des Fehlers die Länge der Daten mit 11 (reicht für höchste Integerzahl) natürlich zu gering waren, und diese ausserdem falsch übertragen wurden, nämlich als SQL_C_CHAR anstelle von SQL_C_DEFAULT. Kurz: es wurde nicht, wie vermutet, ein Key zu den tatsächlichen Daten zurückgeliefert, sondern die ersten Bytes in Hex-Darstellung, aus Hallo wurde so also 48616C6C6F.
Das Problem kann ich natürlich beheben und wird in der nächsten XProfan-Version dann auch behoben 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
25.02.2009  
 




E.T.
RGH
....Kurz: es wurde nicht, wie vermutet, ein Key zu den tatsächlichen Daten zurückgeliefert, sondern die ersten Bytes in Hex-Darstellung, aus Hallo wurde so also 48616C6C6F....


Na dann weiss ich jetzt ja wenigstens, wieso ich beim Auslesen immer die (ersten) Hex-Werte aus dem Blob zurück bekommen habe (mein Post vom 15.02. weiter vorn) .
 
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...
25.02.2009  
 



Für Java und binäre Interbase-BLOBS gäbe es hier Beispielcodes: [...] 
Also wenns in Java geht, sollte es in Profan prinzipiell doch auch klappen...
Da wir hier kein Java-Forum sind, poste ich den Code hier nicht; er zeigt aber doch die einzelnen Schritte recht genau. Vielleicht ersieht man daraus eine Lösung für XProfan.
Gruß
Specht

P.S.: JDBC kann über ein einfaches Brückenprogramm auf ODBC-ansprechbare Datenbanken zugreifen, behauptet [...]  Schlimmstenfalls könnte Profan ja ein kleines Java-Programm fernsteuern, daß das Zeug wie beschrieben ordnungsgemäß rausholt. Zugegeben, reichlich unelegant...
 
25.02.2009  
 




RGH
Peter Specht
Für Java und binäre Interbase-BLOBS gäbe es hier Beispielcodes: [...] 
Also wenns in Java geht, sollte es in Profan prinzipiell doch auch klappen...
Da wir hier kein Java-Forum sind, poste ich den Code hier nicht; er zeigt aber doch die einzelnen Schritte recht genau. Vielleicht ersieht man daraus eine Lösung für XProfan.
Gruß
Specht


Hallo,
das habe ich auch schon gefunden, zeigt aber keine (derzeit) in XProfan mögliche Lösung auf, hilft Dietmar also leider nicht weiter. Hier wird zunächst ein SQL-Aufruf vorbereitet, anschließend werden einzelne Felder mit Daten gefüllt und erst im dritten Schritt wird das SQL-Statement ausgeführt.
Selbst wenn der ODBC-Treiber diese Technik unterstützen würde, so kann es XProfan derzeit nicht. SQLExec führt das Statement gleich aus (gegebenenfalls vorberhaltlich eines COMMIT-Befehles - siehe Transaktionen).

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
25.02.2009  
 




Uwe
''Pascal''
Niemeier
Hi Leute!

Wenn ich das richtig sehe, fehlt eine Syntax für den Treiber (bzw. ist keine bekannt), um eine Datei direkt in den BLOB zu schreiben?

Dazu zwei Fragen:

1. Hat jemand eine (theoretische) Möglichkeit gefunden, per ODBC/SQL Streams  zu nutzen (davon war irgendwo im WWW ein paar mal die Rede, glaube ich)?

2. Gibt es irgendein Programm, das definitiv unter Nutzung der ODBC-Treiber Dateien in BLOBs schreiben kann? Könnte zu Testzwecken sinnvoll sein...

SeeYou
Pascal
 
26.02.2009  
 




RGH
Hallo,

ich habe mal in der ODBC-API (ich habe hier einige hundert ausgedruckte Seiten des msn) und den oben genannten Quellen gestöbert. Es dürfte in der Tat per ODBC-Treiber gehen, aber vermutlich nicht bei allen Datenbanken per einfachem direkt mit SQLExecDirect ausgeführtem SQL-Statement. (In XProfan gehe ich den Weg über SQLExecDirect.) Bei FireBird ist eben die Länge dieses Statements auf 64 kB begrenzt.

Folgender Weg anstelle des SQLExecDirect müßte klappen:
- Ein SQL-Befehl mit SQLPrepareStatement und ? für die Daten vorbeiten, etwa mit dem Statement INSERT INTO MeineTabelle (MeinBlob) VALUES (?). Der Rückgabewert ist ein Handle dieses vorbereiteten Statements.
- Die Daten per Zeiger/Länge mit SQLPutData nachschieben
- Das Statement mit SQLExecute ausführen.
Diesen Weg kann man natürlich für alle Datentypen gehen und er geht auch für UPDATE.
Das sollte per API-Aufrufe natürlich auch in XProfan möglich sein. (Da ich hier in der Firma natürlich kein FireBird auf meinem Rechner installieren darf und kann, hoffe ich vielleicht Sonntag Abend zeit zu finden, es auszuprobieren.*)

Gruß
Roland

(Morgen Mittag geht es erst mal für zwei Übernachtungen nach Köln. Ich verbinde die Nutzung des in der Weihnachtsfeierverlosung gewonnenen Hotelgutscheines für zwei Nächte und Personen mit dem Besuch eines Auswärtsspieles der Mannheimer Adler gegen die Kölner Haie. Natürlich hoffen wir am Sonntag rechtzeitig zum Heimspiel gegen die Hamburg Freezers wieder zurück zu sein.)
 
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
26.02.2009  
 




Dietmar
Horn
Hallo,

hier habe ich Beispiele zum Schreiben und Lesen von Firebird-Blobs gefunden - leider nur in Delphi.

Wie könnte man das in XProfan 11 umsetzen?

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:  [...] 
28.02.2009  
 




Dietmar
Horn
Sorry,

im obigen Posting hatte ich den Link zum Delphi-Source für die Blobs vergessen:

[...] 

Weiß jemand, wie man das mit XProfan 11 umsetzen könnte?

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:  [...] 
01.03.2009  
 




Uwe
''Pascal''
Niemeier
Hi Leute!


Mutmaßung: Entweder ist die db-Unterstützungvon Delphi völlig anders gestrickt als die von Profan oder es kommen spezielle Komponenten zum Einsatz.

mir
Gibt es irgendein Programm, das definitiv unter Nutzung der ODBC-Treiber Dateien in BLOBs schreiben kann?


Der Gedanke dahinter war, über die Windows-interne Ablaufverfolgung (unter ODBC einstellbar) die Kommunikation zwischen Programm und Treiber zu protokollieren. Dabei werden sowohl Kommandos als auch API-Aufrufe aufgezeichnet. Das sollte eine Nachbildung der Funktionalität erleichern.

Allerdings ist fraglich, ob diese Möglichkeit effektiver ist als das bereits vorgeschlagene stückweise Aneinanderhängen von Daten. Nach Rolands Aussage ist ja auch das Auslesen großer Datenmengen demnächst ohne API möglich, sodaß man komplett auf externe Funktionen verzichten könnte.
(Selbst ich verwende APIs nur da, wo es nötig ist bzw. sichtbare Vorteile bringt )

@ Roland: Wann wird es einen entsprechenden Patch geben? Es hat sich ja doch einiges angesammelt, was korrigiert werden müßte...

SeeYou
Pascal
 
01.03.2009  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

18.954 Betrachtungen

Unbenanntvor 0 min.
Klaus Kohlhepp20.10.2022
Walter24.02.2022
Rschnett20.02.2019
Peter Max Müller04.02.2019
Mehr...

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie