从其它平台迁移而来
在从数据库中查询数据时,有时需要事先取得字段内容的大小,再根据情况进行处理。
对于ADO
之类返回TField
类型的,可以使用DataSize
属性,但是!!!这里有很深的坑!!!。
首先看如下代码:
1
2
3
4
|
if ADOQuery.FieldByName('Test').DataSize > 3 then
{处理1}
else
{处理2};
|
按预想,当Test
字段里的数据超过3B时,应该执行处理1
的代码,但事实上无论该内容长短,都是执行处理2
的代码,WHY?
扒一下Delphi
的源码就明白了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
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
):
1
2
3
4
|
if TBlobField(ADOQuery.FieldByName('Test')).BlobSize > 3 then
{处理1}
else
{处理2};
|