null datetime value 30/12/1899或01/01/1800

Agu*_*ert 2 delphi ado delphi-xe4

我有以下......

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;
Run Code Online (Sandbox Code Playgroud)

这工作正常但是,当某些Pcs中的"Date"字段为NULL时,LDate为0而另一个为-36522.

任何的想法???谢谢!

编辑:

奇怪的行为是

function TDateTimeField.GetAsDateTime: TDateTime;
begin
  if not GetValue(Result) then Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*nan 6

TDateTime没有空值.这意味着如果数据库具有空日期,那么您的程序是错误的.你需要给这样的日期特殊待遇.只有AsDateTime在确定该字段不为空后才调用.如果遇到空字段,则需要以某种特殊方式处理它,但是TDateTime由于没有这样的值,所以不能将值明确地设置为null.

  • 字段为null时返回的任何值都是错误的.基本上,返回什么值并不重要,因为不能返回有意义的值. (2认同)

who*_*ddy 5

扩展David的答案:处理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;
Run Code Online (Sandbox Code Playgroud)

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

第二种方法是检查值是否真的NULL并且不依赖于隐式转换.

if qryGetData.FieldByName('Date').IsNull then ...
Run Code Online (Sandbox Code Playgroud)