AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze
Thema durchsuchen
Ansicht
Themen-Optionen

"Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

Ein Thema von Bodenseematze · begonnen am 21. Nov 2023 · letzter Beitrag vom 19. Dez 2023
Antwort Antwort
Bodenseematze

Registriert seit: 10. Jul 2023
50 Beiträge
 
#1

"Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 21. Nov 2023, 08:48
Hallo zusammen,

ich habe mal wieder ein Problem, von dem ich absolut nicht verstehe, wo es herkommt bzw. wie ich es umgehen kann.

Ich greife mit Delphi 7 über die BDE auf eine Datenbank auf einem MSSQL-Server 2019 (v15.0.4326.1) zu.
Der Zugriff erfolgt über den MS ODBC-Treiber v18.3 und über die BDE 5.2.0.2
Im Treiber und am Datebank-Eintrag sind bereits "BLOBS TO CACHE" auf 512 und "BLOB SIZE" auf 256 gestellt.

Ich habe eine Form, auf der Datenbankinhalte einer Master-Tabelle (Angebotsdaten) angezeigt und editiert werden können.
Auf dieser Maske ist auch ein DBGrid, in dem Datensätze aus der Detail-Tabelle (Angebotspositionen) angezeigt und teilw. editiert werden können.

In der Detail-Tabelle sind neben den üblichen Preisinformationen (Einzelpreis, Anzahl, Rabatt etc.) und der Positionsnummer auch der Positionstext enthalten.
Dieser ist ein VARCHAR mit 2048 Zeichen.
Damit dieser potentiell lange Text nicht in der Tabelle angezeigt und editiert werden muss, selektiere ich für die Tabelle die ersten 254 Zeichen - das habe ich sowohl als Datenbank-View als auch direkt als SQL-Statement
Code:
CONVERT( VARCHAR(254), LEFT([Text], 254), 0 ) AS [Text_kurz]
im Code versucht.
Die entsprechende Grid-Spalte ist dann als TStringField definiert und auf ReadOnly gesetzt.

Auf der Maske selber ist für die Editierung der Spalte dann noch ein TDBMemo-Feld mit Bezug zu der vollständigen "[Text]"-Spalte...

Beim Öffnen eines Angebots wird zuerst die Mastertabelle über ein TQuery ("Head") mit der angeg. Angebots-ID geöffnet und dann die Detail-Datensätze (ebenfalls ein TQuery "Tail") ebenfalls mit der Angebots-ID geöffnet; dann wird auf die letzte Position positioniert ("Tail.Last()").
Soweit funktioniert alles und sowohl im Grid als auch auf der Maske wird der Text / der verkürzte Text angezeigt.
Beide Queries sind auf
Code:
AutoCalcFields=false, CachedUpdates=True, RequestLive=False, UpdateMode=upWhereKeyOnly
eingestellt; beide haben ein UpdateObject gesetzt, in deren SQL-Statements die Pseudo-Spalte [Text_kurz] nicht verwendet wird.

Da auf der Maske (und im Masterdatensatz) die Gesamtpreise zu sehen sind, muss ich bei jeder Änderung einer Position oder beim Hinzufügen einer neuen Position die Preise neu zusammenrechnen.
Hierzu ist beim Tail-Datensatz eine Event-Methode bei
Code:
OnCalcFields
hinterlegt.
Diese wird aufgerufen und soll dann über eine Schleife die Positionsdatensätze mit
Delphi-Quellcode:
Tail.DisableControls();
Tail.First();
while ( NOT Tail.EOF ) do begin
...
Tail.Next();
end;
Tai.EnableControls();
durchlaufen und die Preise zusammenrechnen.

Sobald ich im Grid anfange zu editieren und dann das Grid verlassen wird, wird auch die Methode aufgerufen.
Blöderweise kommt schon in der o.a. Zeile "Tail.First()" die Exception "Invalid BLOB handle in record buffer" - und zwar auch dann, wenn am Text überhaupt nichts verändert wurde!

Aber warum? Beim Einlesen der Datensätze funktioniert doch auch alles?
Warum kommt diese Meldung dann nach dem Editieren?
Und was kann ich dagegen machen?

Oder: kann ich vielleicht die Preise direkt aus den entsprechenden Grid-Spalten auslesen ohne über das TQuery zu wandern?

Ich bin etwas ratlos gerade...

Übrigens: in meinen Test-Positionen (100 Stück) ist die Text-Länge zw. 130 und 142 Zeichen lang - also weit davon entfernt, abgeschnitten zu werden...

Geändert von Bodenseematze (21. Nov 2023 um 09:21 Uhr) Grund: zus. Infos
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.889 Beiträge
 
Delphi 12 Athens
 
#2

AW: "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 21. Nov 2023, 15:59
Also wir haben folgende ähnlich gelagerte fälle gehabt:
Code:
[B]Ungültiges BLOB-Handle im Datensatzpuffer[/B] Februar/2004
Lösung:
In einem Datensatz war ein defektes Bild gespeichert.
UPDATE PERSONEN SET BILD=NULL
Code:
[B]Ungültiges BLOB-Handle im Datensatzpuffer[/B] Februar/2009 (Nicht alle Kunden wollten updaten...also müssen sie unter der BDE leiden)
Es handelt seich dabei um ein BDE Problem.
Wenn der MS-SQL Server verwendet wird, werden die BLOB Daten gecached.
Die Große des BLOB Caches kann angegeben werden, es ist der Parameter
im FTFW Alias BLOB TO CACHE.
8192 wäre zumbeispiel ein sinnvoller Wert,
-1  wäre das Maximum.
Mal so zwei Auszüge aus der internen Support Datenbank.


Du bist echt der Beste!
BDE->Firedac und Ansi->Unicode Umstellung nicht gemacht...
Ganz besonders bewundere ich den BDE-Masochismus!
Andreas
Monads? Wtf are Monads?

Geändert von QuickAndDirty (21. Nov 2023 um 16:07 Uhr)
  Mit Zitat antworten Zitat
Bodenseematze

Registriert seit: 10. Jul 2023
50 Beiträge
 
#3

AW: "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 4. Dez 2023, 13:08
Mal so zwei Auszüge aus der internen Support Datenbank.
Danke für Deine Ideen - aber beide sind nicht zutreffend.
1.) es handelt sich eigentlich nicht um "echte" Binärdaten sondern nur um länger definierte VARCHAR-Spalten.
2.) die Cache-Größe habe ich bereits angepasst - keine Änderung im Verhalten
(hatte ich beides oben schon beschrieben... )

Wenn ich die o.a. Positionierung Tail.Last() auf den letzten Tail-Datensatz auskommentiere, kommt der Fehler nicht mehr.
Warum das so ist, erschließt sich mir allerdings überhaupt nicht...


Du bist echt der Beste!
BDE->Firedac und Ansi->Unicode Umstellung nicht gemacht...
Ganz besonders bewundere ich den BDE-Masochismus!
Ein wenig Masochismus hat noch keinem geschadet...

Im Ernst: ich würde liebend gerne umstellen - aber das ist ein Mammutprojekt (v.a. wg. den verwendeten 3rd-Party Tools/Komponenten), das bisher nicht finanziert wurde...
...die aktuelle Lösung ist, die alten Programme in Win7-VMs laufen zu lassen - damit kommen die Benutzer (leider) prima zurecht
--> die Masochisten-Arbeit bleibt also bei der Entwicklung (also mir) hängen...

BTW: ich hatte vor einiger Zeit mal versucht, kleinere Teile von den bestehenden Programmen testweise umzustellen (zuerst einmal auf 64-Bit / Unicode) - das hat noch nicht einmal ansatzweise funktionert (es sind auch noch Ur-Ur-Ur-alte, aber sehr wichtige, Programmteile enthalten, die keiner mehr anfassen will, die aus "TurboPascal für DOS"-Zeiten stammen)- und das trotz "Unterstützung" von Embarcadero (die aber eher schlecht war).

Auch die Umstellung von BDE-Komponenten auf ADO-Komponenten ist mir bisher hat nicht gelungen - hier v.a. weil ich keine (einfach) funktionierende Unterstützung für lokale Paradox-Datenbanken gefunden habe (die werden als Zwischenspeicher verwendet, um als Reportdaten zu dienen).
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 4. Dez 2023, 20:13
Hallo,
vielleicht hilft ja der Austausch dieses einen DB-Grids durch ein normales TStringGrid.
Füllen dann halt per "normaler" Query.

Nicht einfach, aber in endlicher Zeit doch lösbar?
Heiko
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.433 Beiträge
 
Delphi 7 Professional
 
#5

AW: "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 4. Dez 2023, 22:38
Der Fehler entsteht aber nicht durch das DB-Grid, sondern durch die Menge der Daten. Da gab's schon immer 'nen Flaschenhals.

Statt BDE einfach mal ADO und den ODBC-Treiber von Windows für Paradox probieren (für Paradoxversionen 3.x, 4.x und 5.x)? Der Treiber ist bei meinem Windows 10 von Haus aus dabei (und war er bei älteren Windosen auch schon - führt halt nur ein Schattendasein, da keiner das wirklich zu nutzen scheint.)

Der Connectionstring könnte dann in etwa so aussehen:
Code:
Provider=MSDASQL.1;Persist Security Info=False;Data Source=InDerODBCVerwaltungVergebenerName;
Oder 'ne DSN-Datei anlegen, die könnte dann in etwa so aussehen:
Code:
[ODBC]
DRIVER=Microsoft Paradox Driver (*.db )
UID=admin
UserCommitSync=Yes
Threads=3
SafeTransactions=0
ParadoxUserName=admin
ParadoxNetStyle=4.x
ParadoxNetPath=C:\Temp
PageTimeout=5
MaxScanRows=8
MaxBufferSize=2048
FIL=Paradox 5.X
DriverId=538
DefaultDir=C:\Temp
CollatingSequence=ASCII
Oder direkt per Verbindungszeichenfolge:
Code:
Driver={Microsoft Paradox Driver (*.db )}; DBQ=c:\temp;DriverID=26
SQLDriverConnect (Paradox-Treiber) SQLConfigDataSource (Paradox-Treiber)

Eventuell mal in der BDE-Configuration mit BLOBS TO CACHE = -1 probieren, ob das Problem dann weggeht. Eventuell aber auch in der TDataBase-Komponente (soweit sie genutzt wird) bei Params mal BLOBS TO CACHE=-1 angeben.
Der Fehler tritt halt auf, wenn mehr Blobfelder / Sätze mit Blobfeldern gelesen werden, als der Zahl, die bei BLOBS TO CACHE angegeben wurde, entspricht.

Invalid BLOB handle in record buffer

Eventuell bei der Benutzung der Komponente TQuery die Eigenschaft RequestLive auf True setzen. In der Delphi 7-Hilfe steht da einiges zu, schau mal nach, ob das eine Option sein könnte. (Bin mir nicht ganz sicher, aber der Blobcache wird dann umgangen, so dass das Problem damit eigentlich nicht (mehr) auftreten sollte.)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.186 Beiträge
 
Delphi 12 Athens
 
#6

AW: "Invalid BLOB handle in record buffer." bei 2. Durchlaufen der Datensätze

  Alt 4. Dez 2023, 23:00
Oder mal versuchen die Daten auszutrennen.

Nja, grundsätzlich ist es eh besser so wenig wie möglich Datensätze Daten zu laden.

* nicht die ganze Tabelle, sondern nur den/die wichtigen Datensätze (Filter / WHERE)
* aktuell "unnötige" Spalten im SELECT weglassen
* Spalten mit gleichen/wiederholenden Daten als MasterDetail über ein/mehrere weitere Datasets angängen
* auch die Blobs könnte man z.B. via MasterDetail auslagern, vielleicht auch manuell, über einen Ladeknopf

Wenn eh kaum gescrollt wird, bzw. die Zeit für das Scrollen nicht so schlimm ist, dann jeweils nur den aktuellen Blob laden
vielleicht auch im Hintergrund den/die Blobs in Ruhe in einen Cache nachladen, anstatt sofort ALLES bei der ersten Abfrage.




Teilweise können auch die DB-Komponenten selbst Teile eigenständig nachladen.
* z.B. den Blob erst laden, wenn drauf zugegriffen wird
* oder nicht alle Datensätze laden, sondern immer nur einen Teilbereich, worin man sich grade befindet
* oder ...

z.B. siehe FetchOptions beim TFDQuery
https://docwiki.embarcadero.com/Libr...y.FetchOptions
https://docwiki.embarcadero.com/Libr...ons_Properties
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 4. Dez 2023 um 23:03 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz