Seite 1 von 1

Mehrere Blobs bei databaseupdate

Verfasst: 05.10.2017 15:07
von ProgOldie
Hallo,
ich habe in einem Datensatz einer SQLITE-DB mehrere BLOBs, in die ich jeweils ein File einlesen will.
Dazu muss ich die Fileinhalte natürlich erst einlesen und dazu wiederum einen Speicherbereich reservieren.
Da ich bei INSERT bzw. UPDATE() alle Bereiche gleichzeitig ansprechen muss, muss ich mir auch für jeden BLOB die zugehörige Adresse und dessen Größe merken, denn ich kann den Bereich (vermutlich!) nicht sofort nach jedem SetDatabaseBlob() wieder freigeben.

Ist das folgende kleine Testprogramm in diesem Zusammenhang unproblematisch oder muss ich dabei mit bösen Überraschungen wie Speicherlecks o.ä. rechnen?

Code: Alles auswählen

EnableExplicit

Dim *mem(5)   ;Bereich für Blobs von 0..4 
Dim size.i(5)
Define Nr.i

For Nr=0 To 4
  size(Nr)=10*Nr + 5  ; irgendeine synthetische Speichergröße
  *mem(Nr)=AllocateMemory(size(Nr))
  Debug Str(*mem(Nr))+"---"+Str(size(Nr))
Next
For Nr=0 To 4
  FreeMemory(*mem(Nr))
Next

Re: Mehrere Blobs bei databaseupdate

Verfasst: 05.10.2017 16:59
von GPI
ProgOldie hat geschrieben:Da ich bei INSERT bzw. UPDATE() alle Bereiche gleichzeitig ansprechen muss, muss ich mir auch für jeden BLOB die zugehörige Adresse und dessen Größe merken, denn ich kann den Bereich (vermutlich!) nicht sofort nach jedem SetDatabaseBlob() wieder freigeben.
Ist in der Hilfe nicht eindeutig angegeben, aber nach DatabaseUpdate() sollte es gefahrlos freigebbar sein.
oder muss ich dabei mit bösen Überraschungen wie Speicherlecks o.ä. rechnen?
Es kann passieren, das kein Speicher mehr frei ist und AllocateMemory() #Null zurückgeben wird. Das sollte man abfangen (zumindest mit einer Fehlermeldung sauber beenden).

Ansonsten: Dim *mem(5) reserviert ein Array von 0-5 - also 6 Elemente.

Es kann auch klug sein, einen ausreichend großen Speicher an Anfang zu reservieren und ihn nicht frei zu geben. Das spart einen immer das neue anlegen und freigeben.

Re: Mehrere Blobs bei databaseupdate

Verfasst: 05.10.2017 18:46
von ProgOldie
Ist in der Hilfe nicht eindeutig angegeben, aber nach DatabaseUpdate() sollte es gefahrlos freigebbar sein.
Ja, doch die eigentliche Frage ist, ob der Speicherbereich auch schon bei setDatabaseBlob() freigegeben wird. Ich vermute allerdings, dass das nicht(!) der Fall ist, sondern dass dabei lediglich eine Art Verknüpfung zum Speicherbereich angelegt wird.

Re: Mehrere Blobs bei databaseupdate

Verfasst: 05.10.2017 18:59
von Bisonte
Erst nach DatabaseUpdate kannst du gefahrlos freigeben. Habe selbiges auch schon probiert.

Aber bei INSERT und UPDATE muss man nicht alle Felder ansprechen.
Es genügt, wenn man die Felder die man eintragen will in dem ersten Block, bzw bei Update in den SET Anweisungen definiert.

Code: Alles auswählen

"CREATE TABLE tabelle(id, bild1, bild2, bild3, length, length2, length3)"
"INSERT INTO tabelle(bild1, length) VALUES (?, " + Str(Length) + ")"

"UPDATE tabelle SET bild1 = ?, Length = " + Str(Length)
Da muss nicht immer die komplette Tabelle stehen. Fehlende Felder bei INSERT werden mit Standardwerten gefüllt, bei UPDATE komplett ausgelassen.

Re: Mehrere Blobs bei databaseupdate

Verfasst: 06.10.2017 16:43
von ProgOldie
Aber bei INSERT und UPDATE muss man nicht alle Felder ansprechen.
Es genügt, wenn man die Felder die man eintragen will in dem ersten Block, bzw bei Update in den SET Anweisungen definiert.
Ich vermute, du meinst folgende Vorgehensweise ( am Beispiel einer Personendatei mit u. a. Foto )
Bei INSERT: zuerst alle 'nicht-BLOBS' eintragen. In einer anschließenden update-Anweisung dann die BLOBS wie Foto
Bei UPDATE: Die gleiche zweischrittige Vorgehensweise.

Das funktioniert aber nicht, wenn die Datenbank so definiert ist, dass ein Foto der Person vorhanden sein muss (z.B. NOT NULL oder CHECK (Länge), weil dann zumindest im ersten Schritt von INSERT der Datensatz nicht gültig ist.

Es hilft also nichts, man muss - was ohnehin eleganter und klarer ist- mit Speicherbereichen arbeiten.