delphi 关于TField.DataSize的坑  
官方Delphi 学习QQ群: 682628230(三千人)
频道

delphi 关于TField.DataSize的坑


关于TField.DataSize的坑


在从数据库中查询数据时,有时需要事先取得字段内容的大小,再根据情况进行处理。


对于ADO之类返回TField类型的,可以使用DataSize属性,但是!!!这里有很深的坑!!!。


首先看如下代码:


if ADOQuery.FieldByName('Test').DataSize > 3 then

  {处理1}

else

  {处理2};

按预想,当Test字段里的数据超过3B时,应该执行处理1的代码,但事实上无论该内容长短,都是执行处理2的代码,WHY?


扒一下Delphi的源码就明白了。


function TField.GetDataSize: Integer;

begin

  Result := 0;

end;


function TStringField.GetDataSize: Integer;

begin

  Result := Size + 1;

end;


function TWideStringField.GetDataSize: Integer;

begin

  Result := (Size + 1) * SizeOf(WideChar);

end;


function TIntegerField.GetDataSize: Integer;

begin

  Result := SizeOf(Integer);

end;


function TLongWordField.GetDataSize: Integer;

begin

  Result := SizeOf(LongWord);

end;


function TSmallintField.GetDataSize: Integer;

begin

  Result := SizeOf(SmallInt);

end;


function TShortintField.GetDataSize: Integer;

begin

  Result := SizeOf(ShortInt);

end;


function TByteField.GetDataSize: Integer;

begin

  Result := SizeOf(Byte);

end;


function TLargeintField.GetDataSize: Integer;

begin

  Result := SizeOf(Largeint);

end;


function TWordField.GetDataSize: Integer;

begin

  Result := SizeOf(Word);

end;


function TFloatField.GetDataSize: Integer;

begin

  Result := SizeOf(Double);

end;


function TSingleField.GetDataSize: Integer;

begin

  Result := SizeOf(Single);

end;


function TExtendedField.GetDataSize: Integer;

begin

  Result := SizeOf(Extended);

end;


function TBooleanField.GetDataSize: Integer;

begin

  Result := SizeOf(WordBool);

end;


function TDateTimeField.GetDataSize: Integer;

begin

  Result := SizeOf(TDateTime);

end;


function TSQLTimeStampField.GetDataSize: Integer;

begin

  Result := SizeOf(TSQLTimeStamp);

end;


function TSQLTimeStampOffsetField.GetDataSize: Integer;

begin

  Result := SizeOf(TSQLTimeStampOffset);

end;


function TDateField.GetDataSize: Integer;

begin

  Result := SizeOf(Integer);

end;


function TTimeField.GetDataSize: Integer;

begin

  Result := SizeOf(Integer);

end;


function TBytesField.GetDataSize: Integer;

begin

  Result := Size;

end;


function TVarBytesField.GetDataSize: Integer;

begin

  Result := Size + SizeOf(Word) {Length Prefix};

end;


function TBCDField.GetDataSize: Integer;

begin

  // SizeOf(TBcd) is used here instead of SizeOf(Currency) because some

  // datasets store the currency data in TBcd format in the record buffer.

  // For these classes (TBDEDataset & TClientDataset) a call to

  // TField.GetData(Buffer, True) will return a TBcd.

  Result := SizeOf(TBcd);

end;


function TFMTBCDField.GetDataSize: Integer;

begin

  Result := SizeOf(TBcd);

end;


function TBlobField.GetDataSize: Integer;

begin

  // Blob data is not stored in the record buffer and can not be read

  // with a call to TField.GetData. Use GetBlobSize instead.

  Result := 0;

end;


function TReferenceField.GetDataSize: Integer;

begin

  Result := FSize + 2;

end;

也就是说,不能直接取DataSize,而是需要转换为实际的类型后再取DataSize,而且TBlobField是特例,需要使用TBlobField.BlobSize。那么,刚才的例子应该这样写(假设字段类型是Blob):


if TBlobField(ADOQuery.FieldByName('Test')).BlobSize > 3 then

  {处理1}

else

  {处理2};


来源:https://my.oschina.net/afrusrsc/blog/3073039


推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.048176050186157 seconds