我在激活 Debug DCUs 选项的情况下调试了下面的代码,奇怪的是 SysUtils.ValidateTimeStamp 将 date = 0 的 TimeStamp 评估为无效,因此抛出 EConvertError 异常(而不是返回 Null 或 Unassigned)。
所以最终结果是对 dsInsert 状态下的空字段执行 OldValue 请求是无效的。该变体永远不会返回,因此如果您使用 (field.OldValue <> Null) 或 VarIsNull(field.OldValue) 对其进行测试,则它是无关紧要的。之前抛出异常。
cds_something 有两个字段(在设计时创建):
- dt_Something
- num_something
代码:
var
b: TClientDataset;
begin
b := cds_somethin;
b.Close;
b.CreateDataSet;
b.Insert;
if b.FieldByName('DT_Sometinhg').OldValue <> Null then
ShowMessage('Something wrong!!!')
else
ShowMessage('Normal');
b.Cancel;
注意:我把这篇文章的原始编辑搞砸了。现在这是对我发现的正确解释。
另外:使用其他一些字段类型(字符串、BCD、浮点数和备忘录)进行测试,并且 OldValue 未分配 - 所以上面的测试将评估为假。
似乎只有 TDateField 和 TDateTimeField 显示该行为。TTimeField 和 TSQLTimeStamp 评估正常 - 但 TSQLTimeStampField.OldValue 既不等于 Null 也不等于 Unassigned (wtf!!)...
代码片段发生了一些变化:
var
b: TClientDataset;
begin
b := cds_somethin;
b.Close;
b.CreateDataSet;
b.Insert;
/*
if (b.FieldByName('DT_Something').OldValue <> Null)
and (b.FieldByName('DT_Something').OldValue <> Unassigned) then
ShowMessage('Something wrong!!!')
else
ShowMessage('Normal');
*/
if (b.FieldByName('ts_Something').OldValue <> Null)
and (b.FieldByName('ts_Something').OldValue <> Unassigned) then
ShowMessage('Something wrong!!!')
else
ShowMessage('Normal');
b.Cancel;
其中 ts_Something 是 TSQLTimeStampField。这些字段是在设计时创建的。