關於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};
相關文章
相關標籤/搜索