我在这里遇到了一个非常奇怪的情况。 我通过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等 为了查看正确的结果,我需要重新打开查询。
有人可以帮忙吗?
答案 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
这非常难看,但它确实可以解决问题..