在從數據庫中查詢數據時,有時須要事先取得字段內容的大小,再根據狀況進行處理。數據庫
對於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};