Forum | | | | - 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:
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 |
| | | 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 3 - |
| | RGH | Hallo Dietmar,also ich würde die Dateien selbst nicht in die Tabelle schreiben, sondern nur den Dateinamen (ggf. mit Pfad) und die Dateien in einem speziellen Verzeichnis sichern.Wenn es sich um reine Textdateien handelt (RTF ist auch reiner Text, halt mit Formatierungsbefehlen), könnte man die Datei in einen String einlesen und diesen in einem entsprechend großem VARCHAR speichen. Beliebige binäre Dateien könnte man mit Encode64 in einen String verwandeln und nach dem Auslesen mit Decode64 wieder zurück. 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 | 09.02.2009 ▲ |
| |
| | Dietmar Horn | Hallo Roland,
nein, das geht so leider nicht, weil der Auftraggeber bzw. die anderen Projektmitlieder die Daten alle möglichts in einer Datei bzw. Datenbank haben möchten. Wer die Musik bestellt und bezahlt, der bestimmt bekanntlich auch, welche Titel gespielt werden (und ggf. auch in welcher Lautstärke) - und welche Titel nicht.
Die Hintergründe:
- Einfacherer Datensicherung für die relativ unerfahreneren PC-Anwender.
- Später soll das Projekt auch netzwerkfähig sein.
- Registrierte Kunden sollen sich mittels einer solchen Datenbank aus einem geschützten Bereich des Internets Datenbanken austauschen und aktualisierte Datenbanken vom Hersteller regelmäßig als Updates runterladen können.
- In einem fortgeschritteneren Stadium des Projektes sollen artverwandte Branchen-Programme gemeinsam auf solche Datenbanken zugreifen und diese nutzen können. Deshalb muß es unbedingt Firebird bzw. Interbase sein und nicht Access, nicht dBase o.ä., was mir persönlich viel lieber gewesen wäre.
- In der Datenbank sind nicht nur Texte enthalten, sondern das kann alles mögliche sein: Texte, Hilfedateien, Bilder, Sounds, Videos, Grafiken, ... Zusammen mit den Anwenderdaten kann die Datenbank im Laufe der Jahre beim Kunden dann bis auf -zig oder hunderte MB und im Extremfall evtl. gar bis in den GB-Bereich anwachsen.
- Dieses Projekt ist keinesfalls der 3978. Aufguß einer primitiven Adressen- oder Programmverwaltung auf Anfänger-Niveau, sondern soll möglichst noch in diesem Jahr kommerziell vertrieben werden können.
Über Alternativen brauche ich dbzgl. mit dem Auftraggeber nicht weiter zu diskutieren - anderenfalls bin ich den Auftrag los, und ich werde da nie wieder einen Fuß in die Tür bekommen.
Bis jetzt habe ich lediglich rausbekommen, daß es dafür in SQL einen Datentyp namens BLOB gibt(?).
Daß es mit einer einzigen Firebird- bzw. Interbase-Datenbank gehen muß, zeigen ja andere professionelle Branchen-Programme auf diesem Gebiet, die das so handhaben.
Dieser BLOB-Krempel ist der einzigste Stolperstein, der mir bei diesem Projekt bis jetzt noch im Wege liegt. Alles andere ist reine Fleiß-Arbeit, wo ich programmiertechnisch mit XProfan irgendwie durch muß. Falls es wegen der riesigen Datenmengen irgendwann mit XProfan zu Geschwindigkeitsproblemen kommen sollte, muß ich das Ganze dann eben mit Profan2Cpp umwandeln und in C compilieren und / oder meine rudimentären Assembler-Kenntnisse von vor ca. 10 - 15 Jahren nochmal auffrischen und mir geschwindigkeitsrelevante Programmteile in Assembler programmieren.
Über andere Alternativen brauche ich mir absolut keinen Kopf zu machen. Es muß zwingend Interbase bzw. Firebird sein - und zwar alles in einer einzigen Datenbank. Weil das im Endeffekt in der Datenbank -zig Tabellen mit je bis zu weit über hundert Feldern und Tausenden Datensätzen pro Tabelle sein können, brauche ich da weder mit dBase, noch mit einer sonstwie augeklügelten Ordnerstruktur mit externen Dateien anzufangen.
Weiß hier wirklich keiner von den SQL-Experten mit BLOB, ALTER DATABASE, etc. umzugehen?
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: [...] | 10.02.2009 ▲ |
| |
| | Thomas Freier | Hallo Dietmar, das mit sql und den Blob-Feldern hatten wir doch gerade erst: [...] einschließlich Encode64. |
| | | | |
| | Dietmar Horn | Hallo,
das SQLite-Demo mit den BLOB-Feldern von Georg nützt mir vorerst so gut wie gar nichts, weil bei SQL mit FB/IB die Befehle etwas anders sind. Und gerade für das BLOB-Zeugs findet man in den Hilfedateien so gut wie gar nichts (jedenfalls nichts für mich Verständliches).
Den ganzen Freitagabend haben Tim H., Mario P. (E.T.), Nico M., Thomas Z. und ich uns den Kopf zermartert und herumprobiert.
Die Vorgehensweise entsprach in etwa der aus dem o.g. SQLite-Demo: von Georg.
Hier mal ein Zwischenergebnis von E.T. und Tim H. von gestern Abend:
declare db&,sql$, Bereich#, Datei$, X1&, Inhalt$,Inhalt2$ , Result&,blub$
cls
Datei$ = C:\Verein\Dho\PROFAN_PROJEKT\Toolbar.bmp
Print (FileSize(Datei$)/1024/1024),MB
Dim Bereich#, FileSize(Datei$)
Result& = @BlockRead(Datei$, Bereich#, 0, FileSize(Datei$))
Inhalt$ = encode64(@Char$(Bereich#,0,FileSize(Datei$)))
Dispose Bereich#
TraceOn
db& = sqlinit(DSN=KursDB;UID=SYSDBA;PWD=masterkey;DBNAME=C:\Verein\DHOPROFAN_PROJEKT\KURSDB.GDB)
If db& > 0
Tabelle löschen, wenn schon vorhanden
Set(Errorlevel,0)
SQLExec DROP TABLE BLOBTESTER;,0
Set(Errorlevel,1)
Tabelle neu erzeugen
sqlExec CREATE TABLE BLOBTESTER ( Feld1 CHAR(40), Name CHAR(40), groesse NUMERIC(15,0), blobtest BLOB ),0
sqlExec INSERT INTO BLOBTESTER(Feld1,Name,groesse,blobtest) VALUES(Dietmar,Timä,1000,:Inhalt$),1einfügen
sqlexec SELECT * FROM BLOBTESTER,0
ClearList
sqlexec SELECT * FROM BLOBTESTER,1
SQLDone
Print @GetCount(0)+1
@DeleteString(0,0)
@DeleteString(0,1)
@DeleteString(0,2)
@DeleteString(0,3)
Print @GetCount(0)+1
Inhalt2$ = Decode64(@MoveListToStr$(@Chr$(1)))
print Inhaltsvergleich:
print ,Left$(Inhalt$ ,40)
print ,Left$(encode64(Inhalt2$),40)
Dim Bereich#, FileSize(Datei$)
Char Bereich#, 0 = Inhalt2$
Print SizeOf(Bereich#)
BlockWrite C:\Verein\Dho\PROFAN_PROJEKT\Toolbar_100.bmp, Bereich#, 0, SizeOf(Bereich#)
Else
MessageBox(Datenbank konnte nicht gefunden werden,,0)
Endif
Dispose Bereich#
Waitinput
end
Das Ding läuft zwar sauber und ohne Fehlermeldungen durch, doch nach dem Auslesen des BLOB-Feldes erhält man jedoch nur Müll (vielleicht ist das Hineingeschriebene ja evtl. auch schon Müll?).
Die Datei als Encode64-String in ein VACHAR zu schreiben bringt keine Punkte, denn diese Textfelder sind auf 32 KB Größe begrenzt, was für die zu speichernden Dateien keinesfalls ausreicht. Das Ausweichen auf SQL mit SQLite, Access, dBase, etc. hilft mir ebenfalls nicht - aus Kompatibilitätsgründen (für später) mit anderen Projekten muß es zwingend Interbase / Firebird mit BLOBs sein.
Roland geht in seinem SQL-Kurs leider auch nur immer auf die einfachsten Grundlagen ein, die inzwischen sogar ich schon längst kapiert habe - mit keinem Wort jedoch auf BLOB-Felder.
Aber irgendwie muß das BLOB-Zeugs doch möglich sein, denn andere Programme verwenden das ja auch. Oder ist etwa XProfans SQLExec-Befehl eingeschränkt, so daß das deswegen nicht funktioniert?
Weiß hier wirklich keiner einen Rat? -> Eine belibige Datei in ein BLOB-Feld schreiben, auslesen, die ausgelesene und ggf. veränderte Datei wieder in das BLOB-Feld reinschreiben und eine Datei in einem BLOB-Feld ggf. löschen.
Aus der XProfan-Hilfe zu SQLExec:
Jeder Datensatz ist ein Eintrag in der Liste und kann maximal 32767 Zeichen enthalten
Daran dürfte unsere bisherige Vorgehensweise gescheitert sein. Meines Wissens nach wird die Datei nicht direkt im BLOB-Feld der Tabelle gespeichert, weder als Bereich, Ebcode44-String, noch 1 : 1 als Sonstirgendwas (sonst würde ja auch VARCHAR ausreichen), sondern irgendwo anders in der Datenbank (wegen auch möglicher Dateigrößen > 32 KB), und in das BLOB-Feld wird lediglich ein Verweis (Adresse?) eingetragen, wo die Datei in der DB genau zu finden ist. Doch wie geht das? Sicherlich fehlen uns da noch ein paar Parameter (doch welche?) - und vor allem die genaue Vorgehensweise und Syntax dafür.
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: [...] | 14.02.2009 ▲ |
| |
| | Thomas Freier | Hast du deine Vorhaben mit ext. Software [...] realisieren können? |
| | | | |
| | E.T. | Ich denke, das Manko liegt daran, das XProfan für den sqlexec-Aufruf keine Bereiche akzeptiert, wie dies andere Sprachen machen. Hab den Nachmittag damit verbracht, mich in den sql-Quatsch einzulesen, da bin ich in den Beispielen darauf gestoßen. Bin eben dabei, die sql-Befehle ohne die XProfan-Interne Behandlung (sqlexec etc.) zu Verarbeiten, mal sehen, wies am besten gelingt (oder Roland bzw. jemand anderes findet eine Lösung). So wie wir das im Bsp. haben, welches Dietmar gepostet hat, funzt das überhaupt nicht. Ich hab mal das DB-Blob mit einem Bild befüllt (per externe Anwendung), selbst beim auslesen per sqlexec Select... kommt nichts brauchbares in XProfan an (wohl, weil Profan das ausgelesene als String betrachtet und dabei beim schaufeln der Daten in die Listbox am Null-Byte aufhört).
Mal sehen, wie sich das entwickelt, aber Dietmar hat mich mit diesem Käse angesteckt |
| | | 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... | 14.02.2009 ▲ |
| |
| | Thomas Zielinski | @Mario: Ich hab da ein paar interessante Sachen in der fbclient.dll (in FB enthalten) gefunden. Genaugenommen 8 Funktionen nur für Blob. Jetzt nur noch die Typen der Parameter (Streams) in Profan in griff bekommen. @Dietmar: siehe Mail |
| | | XProfan X4; Win10 x64 Der Kuchen ist eine lüge! | 14.02.2009 ▲ |
| |
| | E.T. | @Thomas: Ungefähr auf diesem Weg bin ich auch, nur nicht über die dll (hab ich aber auch schon halb auseinandergenommen), sondern per Direktverbindung über den SQL-Server, was ja dann allgemein-gültig sein dürfte. |
| | | 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... | 14.02.2009 ▲ |
| |
| | E.T. | Hm, das Beispiel (ein Stück weiter oben von Dietmar) funktioniert ja soweit. Im Blob steht genau der String, welcher auch übergeben wurde (sieht man schön per FbMaestro ). Wo geht der Inhalt nur flöten ?? Beim Auslesen !! Das Ergebnis des Auslesens per sqlexec SELECT blobtest FROM BLOBTESTER,1 können wir uns ja ansehen, indem wir in die Listbox (wo Profan das Ergebnis ja hineinschreibt) schauen: 1. Zeile: BLOBTEST, also das woher 2. Zeile: -------, wohl nur zu opt. Trennung 3. Zeile: F239FE, die ersten hexadezimalen !!! 6 Stellen aus dem ersten Blob 4. Zeile: wie 3., nur aus dem nächsten Blob-Feld usw. eine Zeile für jedes gefundene BlobFeld. (Bei Feldern des Typs CHAR() steht da der richtige String. Aber diese Felder sind zu klein für größere Datenmengen. Mit einem kleinen Bildchen gehts.)
Da also der zurück-gelesene String falsch ist, muß zwangsläufig auch ein falsches Ergebnis rauskommen.
Der Inhalt in der DB ist schonmal richtig !! Jetzt noch das auslesen...
Edit: Also in Anlehnung an [...] nur noch den richtigen Befehl aus der DLL quetschen... |
| | | 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... | 15.02.2009 ▲ |
| |
| | RGH | Hallo Dietmar,
zum Thema BLOBs und Bilder:
Da BLOBs nicht zum SQL-Standard gehören, gibt es vermutlich keine einheitliche SQL-Syntax, um diese zu schreiben und zu lesen. Hier wäre man auf die Dokumentation zur benutzten Datenbank bzw. den benutzten ODBC-Treibern angewiesen.Ich hatte zwar bisher schon Einiges mit Datenbanken zu tun (Oracle, MySQL, ZIM, ...), aber BLOBs haben wir bislang nicht verwandt, so dass ich mich danmit noch nicht befasst habe. So ganz unbedarft würde ich vermuten, dass diese ähnlich wie Memofelder gehandhabt werde, d.h. in der Tabelle selbst steht nur eine Referenz oder Adresse zu den eigentlichen Daten, die in einer eigenen Tabelle (bei dBase eben .DBT) oder einem eigenen Bereich der Datenbank stehen.
Und das bringt mich auf einen Lösuugsansatz ohne BLOBs:
Tabellen: In der eigentlichen Tabelle habe ich statt des Bildes selbst nur ein Feld Bildnummer. Es gibt eine zweite Tabelle (in derselben Datenbank) mit den Feldern Bildnummer (Zahl), Bildteil (Zahl), Bilddaten (VarChar mit größtmöglicher Länge). Da ein Bild zu groß für ein VarChar sein kann, wird es nötigenfalls in mehrere aufgeteilt.
Bild in Tabellen schreiben: - In die eigentliche Tabelle wird die eindeutige Bildnummer geschrieben. Das kann die Nummer des Datensatzes sein oder eine andere eindeutige Nummer. - Das Bild wird in einen Bereich eingelesen un mit Encode64() in einen String umgewandelt. Dieser kann natürlich über 32 kB groß sein. - Dieser String wird nun in einer Schleife in Teiler zu maximal 32000 Zeichen aufgeteilt und jeder dieser Teile wird in die zweite Tabelle geschrieben, wobei Bildnummer die erwähnte eindeutige Nummer ist und Bildteil von 1 an hochgezählt wird. Auf diese Weise landen nun also auch große Bilder bequem in der Datenbank.
Bild aus Tabelle auslesen: Mit einem SELECT nach der Bildnummer und sortiert nach Bildteil (SORTED BY) werden aus der zweiten Tabelle alle zum Bild gehörenden Teile ausgelesen, zu einem großen String zusammengefügt und mit Decode64() wieder ins ursprüngliche Format zurückgewandelt und inm einen Bereich geschrieben. Dieser kann nun auf die Festplatte geschrieben und angezeigt werden.
Fertig sind die selbstgemachten BLOBs für beliebige Daten!
Einige Hinweise: * Wenn man nicht eh schon das Schreiben und Lesen des gesamten Datensatzes inklusive Bild in einer Transaktion zusammenfasst, sollte man mindestens das Schreiben der Teile eines Bildes in einer Transaktion zusammenfassen. Entweder alle Teile oder gar keiner! (Siehe in der Hilfe unter Einführung, Kapitel 16.4, Absatz Transaktionen)
* Wenn man den Datensatz mit UPDATE verändert und dabei das Bild geändert wird, sollte man in der zweiten Tabelle das alte Bild komplett löschen und neu mit INSERT hineinschreiben. Grund: Wenn das vorherige Bild größer war, bleiben sonst vielleicht Teile davon drin, die beim nächsten Lesen dann Probleme bereiten.
* Sollten mehre Bilder (oder andere große Datenbereiche) in der eigentlichen Tabelle vorkommen, würde ich für jedes dieser Objekte eine eigene Tabelle empfehlen.
Da ich im Moment in der Firma meine Frühstückspause für diese Antwort verwende (anstatt sie mit Butterstange und Capucino aus der Kantine zu begehen), kann ich momentan keinen Beispielcode liefern, aber vielleicht reichen diese Hinweise schon aus. Ansonstenm müßte ich am Wochenende noch mal in die Tasten hauen.
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.02.2009 ▲ |
| |
| | RGH | Hallo Leute,
es ist Sonntag und ich habe etwas Zeit! Hier ein Beispiel, das das oben Genannte demonstriert! Es wird ein Bild in der Datenbank gespeichert und auch unversehrt wieder ausgelesen ... und das Ganze ohne BLUBB ... pardon: BLOB! ;)
Der Einfachheit halber habe ich die beiden Tabellen in der schon weiter oben angelegten (und dort zum Download angehängten) KURSDB hinzugefügt. Der Name des Bildes ist natürlich ebenso anzupassen, wie ggf. der Pfad zur KURSDB. Ich habe versucht, das Beispiel möglichst umfassend zu kommentieren.
declare db&, sql$, bild#, sbild$, datei$, startpos&, teil$, teilnr%, ergebnis$, bildnr%
cls
db& = sqlinit(DSN=KursDB;UID=SYSDBA;PWD=masterkey;DBNAME=D:\Dokumente\FireBird\KURSDB.GDB)
If db& > 0
=================
TABELLEN ERZEUGEN
=================
Tabellen löschen, wenn schon vorhanden
Set(Errorlevel,0)
SQLExec DROP TABLE bilderliste,0
SQLExec DROP TABLE bild,0
Set(Errorlevel,1)
Tabelle für die Liste der Bilder neu erzeugen
SQLExec CREATE TABLE bilderliste (name CHAR(40), fotograf CHAR(40), bildnr INTEGER),1
Tabelle für die eigentlichen Bilder neu erzeugen
SQLExec CREATE TABLE bild (bildnr INTEGER, teil INTEGER, bilddaten VARCHAR(32000)),1
=========================
BILD IN TABELLE SPEICHERN
=========================
Da zu einem Bild mehrere Datensätze gehören, alle Datensätze eines Bildes ineiner Transaktion
zusammmenfassen
Zunächst also die automatische Bestätigung einzelner SQL-Befehle ausschalten. Die folgenden
SQL-Befehle werden also erst mal zwischengespeichert ohne wirklich in die Datenbank zu gehen
sqlexec #AUTOCOMMIT_OFF, 0
Tabelle Bilderliste füllen: Bild 1 hinzufügen
sql$ = INSERT INTO bilderliste VALUES (Helloween Muffins,Jasmin Hülsmann,1)
sqlexec sql$,0
Nun das Bild in Bild# einlesen
datei$ = HELLOWEEN.JPG
Dim Bild#, FileSize(datei$)
BlockRead(datei$, Bild#, 0, FileSize(datei$))
Das Bild in einen String umwandeln
SBild$ = Encode64(Char$(Bild#,0,FileSize(datei$)))
Den String SBild$ in Teilen zu je 32000 Bytes in die Tabele bild schreiben
startpos& = 1 erstes Zeichen des Teilstrings in startpos&
teilnr% = 1 Nummer des aktuellen Teilstrings
While startpos& < Len(SBild$)
teil$ = mid$(SBild$, startpos&, 32000) teil aus dem String bilden
sql$ = INSERT INTO bild VALUES (1,:teilnr%,:teil$) und in Tabelle einfügen
sqlexec sql$,1
startpos& = startpos& + 32000 Startposition im String hochzählen
teilnr% = teilnr% + 1 teilnummerhochzählen
EndWhile
Wenn bis hierher alles glatt gegangen ist, konnten alle Datensätze eines Bildes geschrieben
werden. Es erfolgt also die Bestätigung, dass es nun wirklich in die Datenbank kann:
sqlexec #COMMIT, 0
Für die folgenden Befehle benötigen wir die Transaktionskontrolle nicht mehr, so dass
jede SQL-Anweisung automatisch bestätigt werden soll:
sqlexec #AUTOCOMMIT_ON, 0
=========================
BILD AUS TABELLE AUSLESEN
=========================
Ein Bild aus der Tabelle Bilderliste auswählen
sql$ = SELECT * FROM bilderliste
clearlist
sqlexec sql$,1
Überschrift und Trennzeile entfernen
DeleteString(0,0)
DeleteString(0,0)
ergebnis$ = listbox$(Bild auswählen und mit OK bestätigen:,2)
if ergebnis$ >
Die Nummer des gewählten Bildes steht im dritten Feld
bildnr% = Int(Val(SubStr$(ergebnis$,3,|)))
Jetzt alle Teilstrings zum gewünschten Bild aus der Tabelle bild in richtiger Reihenfolge auswählen
Wir benötigen nicht alle Spalten, sondern nur die Bilddaten
sql$ =SELECT bilddaten FROM bild WHERE bildnr = :bildnr% ORDER BY teil
clearlist
sqlexec sql$,1
Überschrift und Trennzeile entfernen
DeleteString(0,0)
DeleteString(0,0)
Den Gesamtstring aus den Teilen wieder herstellen
sbild$ =
WhileLoop 0, %getcount
sbild$ = sbild$ + trim$(substr$(listboxitem$(&loop),1,|))
EndWhile
Das Bild in seine Byteform zurückverwandeln ...
sbild$ = Decode64(sbild$)
... eine Bereichsvariable auf passende Größe bringen
Clear Bild#
Dim Bild#, Len(sbild$)
... und das Bild hineinspeichern
Char Bild#,0 = sbild$
Bild auf Festplatte speichern
blockwrite GelesenesBild.jpg, Bild#, 0, SizeOf(Bild#)
Bild zur Kontrolle anzeigen
DrawSizedPic GelesenesBild.jpg, 0, 0 - 400, 300, 0
EndIf
SQLDone
Else
Print Datenbank konnte nicht geöffnet werden!
Endif
waitinput
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 | 22.02.2009 ▲ |
| |
| | | Es gibt 8 verschiedene BLOB-Subtypen, nachzulesen auf [...] Für Binärdaten wie Bilder ist eigentlich ohnehin der Defaultmodus 0 vorgesehen. Aber vielleicht kommt da ja einiges schon beim Speichern in die Quere? Ich würde den BLOB-Subtype 0 explizit vor dem Schreiben und vor dem Lesen anfordern, nur zur Sicherheit. Vielleicht klappts dann ja.
Gruss, Specht |
| | | | |
|
AntwortenThemenoptionen | 18.956 Betrachtungen |
ThemeninformationenDieses Thema hat 9 Teilnehmer: |