关于TField.DataSize的坑

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

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

首先看以下代码:code

if ADOQuery.FieldByName('Test').DataSize > 3 then
  {处理1}
else
  {处理2};

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

扒一下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):it

if TBlobField(ADOQuery.FieldByName('Test')).BlobSize > 3 then
  {处理1}
else
  {处理2};
相关文章
相关标签/搜索