ParamByName('xxx').AsBytes truncates data

ParamByName('xxx').AsBytes truncates data

Postby Wade » Mon 15 Jul 2013 01:13

Version 4.0.1
Also we are running IBDAC 4.5.9 which has the same problem described below.

FB 2.5.2, Delphi XE2 - but the problem is not dependent on these factors.

In our code, we have a syntax like this:

Code: Select all
Qry: update MyTable set MyBlob = :MyBlob where MyID = :MyID

var
  b: TBytes;

b := ...;  // A blob of length 70552;
...
Qry.ParamByName('MyBlob').AsBytes := b;
Qry.ExecSQL;


When this query is executed, the data stored in the database is only 5016 bytes (with the input TBytes being 70552 in my test case).

Interestingly, the difference between what should be stored (70552) and what is stored (5016) is 65536.

Digging deeper into the DbxIda and IBDac code we found this:

TIBCParamsDesc.SetAsVariant() has handling that looks like nothing greater in length than 65535 ("WORD") is expected.

Code: Select all
BufferOffset := SizeOf(Word)
...
Marshal.WriteInt16(FValue, Len)


and the result is that the number of bytes stored is "BytesLength MOD 65536".

Is this by design or is it an outright oversight that a WORD is used to store the length?
Wade
 
Posts: 31
Joined: Sun 03 Jan 2010 06:04

Re: ParamByName('xxx').AsBytes truncates data

Postby AndreyZ » Mon 15 Jul 2013 07:19

This is a restriction of InterBase and Firebird. To avoid the problem, you should pass the blob data using the AsBlob property. Here is an example:
Code: Select all
var
  b: TBytes;

b := ...;  // A blob of length 70552;
...
Qry.ParamByName('MyBlob').AsBlob := b;
Qry.ExecSQL;
AndreyZ
 

Re: ParamByName('xxx').AsBytes truncates data

Postby Wade » Mon 15 Jul 2013 18:26

Fair enough, thanks. But shouldn't you raise an error rather than silently storing corrupt data?
Wade
 
Posts: 31
Joined: Sun 03 Jan 2010 06:04

Re: ParamByName('xxx').AsBytes truncates data

Postby AndreyZ » Tue 16 Jul 2013 06:53

Thank you for the suggestion. We have added the generation of an error in case when the parameter size is greater than SizeOf(Word). This functionality will be included in the next IBDAC build.
AndreyZ
 


Return to dbExpress driver for InterBase & Firebird