【问题标题】:null datetime value 30/12/1899 or 01/01/1800空日期时间值 30/12/1899 或 01/01/1800
【发布时间】:2013-12-05 14:40:51
【问题描述】:

我有以下...

var
  LCnn: TADOConnection;
  qryGetData: TADOQuery;
begin
  ...
  //build a connection string to a SQL Server 2008
  ...
  qryGetData.Connection := LCnn;
  qryGetData.SQL.Text := 'SELECT * FROM MYTABLE'
  ...
  LDate := qryGetData.FieldByName('Date').AsDateTime; //Date its a datetime field in the table

end;

这很好用,但是当“日期”字段在某些 PC 中为 NULL 时,LDate 为 0,而在另一个中为 -36522。

知道吗??? 谢谢!

编辑:

奇怪的行为是

function TDateTimeField.GetAsDateTime: TDateTime;
begin
  if not GetValue(Result) then Result := 0;
end;

在第一种情况下,GetValue 结果为假,因此 GetAsDateTime 结果为 0,在第二种情况下,GetValue 结果为真,因此返回 -36522 (01/01/1800)

【问题讨论】:

  • 您的日期字段实际上是定义为数据库中的日期字段还是包含类似日期值的字符串字段,并且您依赖 FieldByName('Date').AsDateTime 进行转换给你?
  • 如果您对相同数据得到不同的结果,请检查两台机器上安装的 OleDb 提供程序版本。
  • 所有电脑都使用同一个数据库吗?如果不是,数据库是否来自同一制造商(MSSQL、Oracle、Firebird 等)?
  • 是的,我们使用的是同一个数据库(MSSQL2008制造商)
  • 我很确定这是一个环境问题,但不知道是什么。

标签: delphi ado delphi-xe4


【解决方案1】:

TDateTime 没有空值。这意味着如果数据库有空日期,那么你的程序是错误的。您需要对此类日期进行特殊处理。仅在确定该字段不为空后才调用 AsDateTime。如果您遇到空字段,您需要以某种特殊方式处理它,但您不能在 TDateTime 中放置一个明确表示 null 的值,因为没有这样的值。

【讨论】:

  • 是的,我同意你的观点。但是在某些情况下返回 0 或 -36522 是有原因的。我正在尝试理解这种行为
  • 当字段为空时返回的任何值都是错误的。本质上,返回什么值并不重要,因为无法返回有意义的值。
  • @AgustinSeifert:关键是这个值是NULL,任何一个NULL值的转换都是没有意义的
  • 但是,我可以知道 AsDateTime 究竟为 null 值返回了什么吗?昨天我得到了你关于当值为空时 AsString 的返回值的答案。 :-)
  • 阅读日期时间TField后代的源码找到我们的
【解决方案2】:

扩展大卫的回答: 处理NULL 日期问题的一种方法是调整您的查询,使其不返回NULL,而是使用sql COALESCE 语句返回任意日期。

qryGetData.SQL.Text := 
'SELECT Id, COALESCE(Date, '''1/1/1900 00:00:00'''), WhatEverFieldYouNeed FROM MYTABLE';
...
LDate := qryGetData.FieldByName('Date').AsDateTime;

这样您可以检查日期的年份是否为 1900(这意味着 DB 值为 NULL)并进行相应处理。确保明智地选择默认日期值,使其不属于数据库中的预期日期范围。

第二种方法是简单地检查该值是否真的是NULL,并且不依赖于隐式转换。

if qryGetData.FieldByName('Date').IsNull then ...

【讨论】:

  • +1 我喜欢 COALESCE 方法,只要你能找到合适的定点日期
  • 在只有一个空条件要评估的情况下,ISNULL 是一种比 COALESCE 更好的方法(开销更少)。但是,差异几乎是微不足道的
  • 感谢您的回答,但这不是我需要的。我知道如何避免这个问题,但我试图找出它发生的原因。我有遗留代码,需要知道这种行为。不过还是谢谢
  • 您确定数据库架构完全相同吗?可以在列上定义一些默认值吗?
猜你喜欢
  • 2021-02-17
  • 2021-04-23
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2017-12-28
相关资源
最近更新 更多