ParamByName('xxx').AsBytes truncates data

Discussion of open issues, suggestions and bugs regarding usage of dbExpress drivers for InterBase & Firebird in Delphi and C++Builder
Post Reply
Wade
Posts: 31
Joined: Sun 03 Jan 2010 06:04

ParamByName('xxx').AsBytes truncates data

Post by 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?

AndreyZ

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

Post by 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;

Wade
Posts: 31
Joined: Sun 03 Jan 2010 06:04

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

Post by Wade » Mon 15 Jul 2013 18:26

Fair enough, thanks. But shouldn't you raise an error rather than silently storing corrupt data?

AndreyZ

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

Post by 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.

Post Reply