How to read data from blob field defined in Oracle 8 i using delphi?

fiwa

Member
This is the code to write Blob Data to a Blob Field (this works).

LOB := TLOBLocator.Create(BlobDataSet.Session, otBLOB);
MS:= TMemoryStream.Create;
MS.WriteComponent(Layout);
mssize := MS.Size;
SQL := ' INSERT INTO TBLLAYOUT '
+ ' ( ID , ... , LAYOUT, LAYOUTSIZE ) '
+ ' VALUES '
+ ' ( '
+ ' :ID '
...
+ ' , empty_BLOB()'
+ ', ' + IntToStr(MS.Size)
+ ' )Returning LAYOUT into :LAYOUT';

Query.SQL.Text:= SQL;
// Assign it to the returning variable
Query.ClearVariables;
Query.DeclareVariable('ID', otFloat);
Query.DeclareVariable('Layout', otBLOB);
Query.SetVariable('ID', seqnr);
Query.SetComplexVariable('LAYOUT', LOB);
Query.Execute;
// After the insert, use the LOB Locator
// to write the data
LOB.Write(MS, mssize);

With the code below I wanted to read the data from a blob field into a Layout(TComponent), but that doesn't work.

LOB := TLOBLocator.Create(tab.Session, otBLOB);
SQL := 'SELECT Layout, LAYOUTSIZE FROM TBLLAYOUT '
+ 'WHERE ID = 197';
Query.SQL.Text := SQL;
Query.Execute();
if not Query.EOF then
begin
layoutsize := StrToInt(FloatToStr(FQuery (Query,'LAYOUTSIZE'),0));
LOB:= Query.LOBField('LAYOUT');
LOB.Seek(0, soFromBeginning);
anz := LOB.Read(MS, layoutsize);
MS.Position := 0;
MS.ReadComponent(Layout);
end;
 
Hello Marco,
if i want to read the blob data
i get the message 'Access violation at Address ...'.
This occurs when I get to
MS.Position := 0;
 
I see. This does not seem quite right:

anz := LOB.Read(MS, layoutsize);

TStream.Read reads a number of bytes from an untyped buffer, and not from another TStream. You can use CopyFrom instead:

anz := LOB.CopyFrom(MS, layoutsize);
 
Thank you for your suggestion.
I tried this code but I get an exception EReadError with the message 'Stream read error' when I pass Lob.CopyFrom.

layoutsize := StrToInt(FloatToStr(FQuery(Query,'LAYOUTSIZE'),0));
LOB:= Query.LOBField('LAYOUT');
LOB.Seek(0, soFromBeginning);
anz:= LOB.CopyFrom(MS, layoutsize);
MS.Position := 0;
MS.ReadComponent(Layout);
 
If I interpret your code correctly we need to do this the other way around?

LOB:= Query.LOBField('LAYOUT');
anz:= MS.CopyFrom(LOB, 0);
MS.Position := 0;
MS.ReadComponent(Layout);
 
Hello Marco, I tried your code but I get also an exception EReadError with the message 'Stream read error'.
 
Hello Marco at the line
MS.ReadComponent(Layout);
I get the exception class EReadError with the message 'Invalid stream format'.
 
This would indicate that the data read from the database is not something that TStream.ReadComponent expects.

Looking at the code that writes the data, this does indeed not seem correct. You should replace this line:

LOB.Write(MS, mssize);

with this:

LOB.CopyFrom(MS, 0);

Note that TStream.Write is a low-level function to write data from memory to a stream. It should not be used to copy data from one stream to another.
 
Back
Top