关于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