#1 2014-02-25 17:47:54

Celso
Member
Registered: 2013-05-14
Posts: 55

Save a blobfield in a TMemoryStream

Before I used this:

sqlPage: TFDQuery;
myconnection  :TFDConnection;
v_ms     : TMemoryStream;

sqlPage.Connection      := myconnection;
sqlPage.SQL.Add('SELECT BLOBFIELD FROM MYTABLE');
sqlPage.Open;
v_ms := TMemoryStream.Create;
(sqlPage.FieldByName('BLOBFIELD') as TBlobField).SaveToStream(v_ms);

Today i use:

Props: TSQLDBConnectionProperties;
v_SQL        : RawUTF8;
Rows             : ISQLDBRows;

Props :=TSQLDBFireDACConnectionProperties.Create(Server,Database,UserName,Password);
 v_SQL := trim(StringToUTF8('SELECT BLOBFIELD FROM MYTABLE'));
Rows := Props.Execute(v_SQL,[]);

My question: How do I get the field and save to a TMemoryStream, as I did before?

Offline

#2 2014-02-25 20:00:21

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: Save a blobfield in a TMemoryStream

You can use:

v_ms: TStream;

...
Props :=TSQLDBFireDACConnectionProperties.Create(Server,Database,UserName,Password);
v_SQL := trim(StringToUTF8('SELECT BLOBFIELD FROM MYTABLE'));
Rows := Props.Execute(v_SQL,[]);
if Rows.Step then begin
  v_ms := TRawByteStringStream.Create(Rows.ColumnBlob(0));
  try

  finally
    v_ms.Free;
  end;
end;

Note that using a Props instance and a Rows interface in the same function/method will probably generate some GPF since Props.Free may be run before Rows statement will be released.
The best is to use a shared fProps field in your main class.

BTW, why are you using TSQLDBFireDACConnectionProperties and not a direct connection?

Offline

#3 2014-02-25 21:26:56

Celso
Member
Registered: 2013-05-14
Posts: 55

Re: Save a blobfield in a TMemoryStream

Thanks for the feedback.

But it did not work. My Blob field is not string. Is there another way?

About your tip "Props instance and the Rows interface in the same function / method", I'll follow and appreciate.

About your question TSQLDBFireDACConnectionProperties, for this example, I'm using the Firebird database. And from what I saw, it was the only way of connection. If you have other tips, let me know.

Offline

#4 2014-02-26 14:26:03

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: Save a blobfield in a TMemoryStream

Celso wrote:

But it did not work. My Blob field is not string.

ColumnBlob() returns a BINARY content encoded within a RawByteString - so it is not a string, but a BLOB, which can be accessed via a TRawByteStringStream class.

Celso wrote:

About your question TSQLDBFireDACConnectionProperties, for this example, I'm using the Firebird database. And from what I saw, it was the only way of connection. If you have other tips, let me know.

FireBird can also be accessed via ZEOS/ZDBC, which is faster when retrieving one row of data, but slower when inserting a lot of data.
See the benchmarkes published on our blog.

Offline

#5 2014-02-26 18:20:28

Celso
Member
Registered: 2013-05-14
Posts: 55

Re: Save a blobfield in a TMemoryStream

In my database, the blob field value is a compress (Zlib.ZCompress) and looks like this:
xÚ•“[nà Eÿ+uw®=<üàsbHD•˜œ¨û_I‰ó¨¢¸qr‘Ð ÝÃŒ˜üèbð¸‰V_BÇmRWŠÓïo€ì*j*IB!ñÖðïó!bV²$m
©í'QQ[e¸µ&B…R:ûE):S¨®¿¿ê'!M¹„olC.àêªk*ˆì2.•@ÿ…»4Æpµégpi„ÒfïžÁ‘‘³Ù[ùž³Ë9\š¢^Äͱ©Ö­ÊÏ}éÏÖ袩ŸnÒ„û°¾ñåFK{écKu!Õ©ïÇD7ð°qqœW4á8øÔ‡Áºœ~äUˆì¡ò<ƒKMŠ>ÈÔ~À|)16{#Ã!×1怱;W.ãkîiÏ°!G'ðÆ
½Ïeôìøüòl_>Ó    ÿŸ#ª4

When I use the process that you showed me, the recovered data looks like this:
'x'#0'•'#6'ýÿ['#0'n'#0'ýÿ '#0#$10#0'E'#0'ýÿ+'#0'u'#0#$F#0'w'#0#1#0'ýÿ='#0'<'#0'ýÿýÿs'#0'b'#0'H'#0'D'#0'ýÿýÿ'#$16#0'ýÿýÿýÿ_'#0'I'#0'ýÿbÛ¸Üq'#0'r'#0'ýÿýÿ '#0'ýÿÌ'#0'ýÿ'#1#0#$18#0'ýÿýÿb'#0'ýÿ'#$17#0'ýÿV'#0'_'#0'B'#0#$12#0'ýÿm'#0'R'#0'W'#0'ýÿýÿ'#$19#0'ýÿo'#0'ýÿýÿ*'#0'j'#0'*'#0'I'#0'B'#0'!'#0'ýÿýÿ'#6#0'ýÿýÿýÿ!'#0'b'#0'V'#0'ýÿ$'#0'm'#0#$A#0'ýÿýÿ'#$19#0''''#0'Q'#0'Q'#0'['#0'e'#0'ýÿ'#$11#0'ýÿ&'#0'B'#0#$1F#0'ýÿýÿ'#$1F#0'R'#0':'#0'ýÿE'#0')'#0':'#0'S'#0'ýÿýÿýÿýÿýÿ'#6#0''''#0'!'#0#$1A#0'M'#0'ýÿýÿo'#0'l'#0'C'#0'.'#0'ýÿýÿk'#0'*'#0'ýÿýÿ2'#0'.'#0'ýÿ@'#0'ýÿýÿ'#$1D#0'ýÿ4'#0'ýÿp'#0'ýÿýÿg'#0'p'#0'i'#0'ýÿýÿf'#0#$E#0'ýÿýÿ'#$15#0'ýÿýÿýÿýÿ['#0'ýÿ'#$14#0'ýÿýÿýÿ9'#0'\'#0'ýÿýÿ^'#0'ýÿq'#3'ýÿ'#2#0#$AD#5'ýÿýÿ}'#0#$C#0'ýÿýÿýÿ©ˆ'#$17#0'ýÿn'#0'„'#4'ýÿýÿýÿýÿýÿF'#0'K'#0'{'#0'ýÿc'#0'K'#0'u'#0'!'#0'i'#5'ýÿýÿ'#5#0'D'#0'7'#0'ýÿ'#$18#0'ýÿq'#0'q'#0#$1A#0'ýÿW'#0'4'#0'ýÿ8'#0'ýÿ'#7#5'ýÿýÿýÿ'#$1C#0'~'#0'ýÿU'#0'ýÿýÿýÿ'#$18#0'<'#0'ýÿK'#0'M'#0'ýÿ>'#0'ýÿýÿ'#$F#0'~'#0'ýÿ'#3#0'|'#0#8#0')'#0'1'#0'6'#0'{'#0#$17#0'#'#0'ýÿ!'#0'ýÿ1'#0'1`'#$E#0';'#0'W'#0'.'#0'ýÿk'#0'ýÿ'#$19#0'i'#0'ð'#3'!'#0'G'#0#1#0#3#0''''#0'ýÿýÿ'#$D#0'ýÿÁ'#3'e'#0'ýÿýÿ'#$7F#0'ýÿ'#$7F#0'ýÿ'#5#0#$1D#0'ýÿl'#0'_'#0'>'#0'ýÿ'#9#0'ýÿ'#5#0'ýÿ#'#0'ýÿ4'#0

and thus can not do the uncompress

Offline

#6 2014-02-26 19:22:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: Save a blobfield in a TMemoryStream

So there is an issue in the SynDBFireDac library, perhaps.
Perhaps you may use your debugger and step in the code (SynDB/SynDBDataSet/SynDBFireDac) and find out what is happening.

Which version of Delphi are you using?

Offline

#7 2014-02-26 20:18:45

Celso
Member
Registered: 2013-05-14
Posts: 55

Re: Save a blobfield in a TMemoryStream

Delphi XE5 Version 19.0.13476.4176

I'll do a test by changing the connection to ODBC

Offline

#8 2014-02-27 17:00:45

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: Save a blobfield in a TMemoryStream

Put a breakpoint in TSQLDBDatasetStatementAbstract.ColumnBlob() and check where it goes.

Offline

Board footer

Powered by FluxBB