在DbNavigator Delphi上按下刷新后错误的结果

时间:2009-12-08 09:42:07

标签: database delphi ado calculated-columns

我在这里遇到了一个非常奇怪的情况。 我通过JET访问数据库(MDB)。我使用DBGrid和DBNavigator来允许用户访问它。使用TADOQuery组件创建数据集,并使用以下查询:

SELECT *, (DateDiff ('y',[Birth Date], Now())) AS [Age] FROM TableName

工作正常。但是每当我按下DBNavigator上的“刷新”按钮时,此计算字段的结果都会出错。例如,如果通常我在Age列上显示7,则在按Refresh后它变为40149, 7改为40149,6改为40150,0改为40156等 为了查看正确的结果,我需要重新打开查询。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:4)

请尝试以下操作,以天为单位返回年龄。

SELECT *, CINT(Now()-[Birth Date]) as AGE FROM TableName

对于多年的使用年限:

SELECT *, INT((Now()-[Birth Date]) / 365.242199) as AGEYRS from TableName

(注意,CINT轮次,INT不会)

这样做的原因是ACCESS以与Delphi类似的方法存储其日期/时间,作为浮点数,其中整数部分是特定日期以来的天数,小数部分是当天的小数部分(0.25 =早上6点,0.50 =中午等)。因此,如果您想知道两天之间的差异,只需记录日期数字之间的差异...数年,将其除以一年中的天数。

修改

这里的另一个选择是在Delphi中创建一个计算字段并在那里执行逻辑。在onCalculated事件中,您将编写如下代码:

procedure TForm1.ds1CalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('CALCDATE').AsInteger := 
    Trunc((Date - DataSet.FieldByName('BIRTH DATE').AsDateTime) / 365.242199);
end;

修改

还有第三种方法。而不是允许刷新按照当前的工作方式,通过使用导航器的onClick来覆盖行为并强制关闭/重新打开数据集:

procedure TForm1.dbnvgr1Click(Sender: TObject; Button: TNavigateBtn);
begin
  if Button = nbRefresh then
    begin
      ds1.Close;
      ds1.Open;
    end;
end;

答案 1 :(得分:1)

请尝试使用此间隔参数:

SELECT *, (DateDiff ('yyyy',[Birth Date], Now())) AS [Age] FROM TableName

以下是“间隔”的含义:

yyyy    Year
q   Quarter
m   Month
y   Day of Year
d   Day
w   Weekday
ww  Week
h   Hour
n   Minute
s   Second

答案 2 :(得分:1)

我使用您之前的评论进行了测试,我也有同样的错误。

我认为这是导航器或喷气机中的某个错误。

点击导航时刷新。显示的40149是没有计算的东西的日期表示。它似乎只使用找到的第一列并显示它。

如果您尝试将其强制转换为字符串,则显示的数据仍为日期时间。

Select *, ' ' & DateDiff(.......) as [Age] From table1;

当我在计算字段中首先使用String或Number类型的列时,结果将按原样显示。 你可以尝试:

SELECT *,  mid(id & (DateDiff ('y',[madate], Now())), len(id) + 1) AS [Age] FROM Table1

或者:

SELECT *,  (id-id) + (DateDiff ('y',[madate], Now()))  AS [Age] FROM Table1

这非常难看,但它确实可以解决问题..