在从数据库中查询数据时,有时须要事先取得字段内容的大小,再根据状况进行处理。数据库
对于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};