【问题标题】:Wrong Result after Refresh pressed on DbNavigator Delphi在 DbNavigator Delphi 上按下刷新后的错误结果
【发布时间】:2009-12-08 09:42:06
【问题描述】:

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

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

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

有人可以帮忙吗?

【问题讨论】:

    标签: database delphi ado calculated-columns


    【解决方案1】:

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

    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;
    

    【讨论】:

    • 这是我最初的想法,我已经尝试过了。它没有用。使用 dbnavigator 刷新时使用 CINT 时 ADO 抛出和错误。而 INT 函数什么也不做,因为 40149 是一个 INT...
    • 只是因为输入的日期没有时间。内部结构还是float,所以需要int。我编辑了我的答案,并使用正常工作的 Delphi 计算字段添加了另一种方法。
    【解决方案2】:

    试试这个区间参数吧:

    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
    

    【讨论】:

    • 我需要计算年龄
    【解决方案3】:

    我用你之前的评论做了一个测试,我也有同样的错误。

    我认为这是 Navigator 或 jet 中某处的错误。

    当您在导航上点击刷新时。显示的 40149 是将日期表示为双精度,没有计算出的东西。它似乎只使用找到的第一列并显示它。

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

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

    当我首先在计算字段中使用字符串或数字类型的列时,结果将按应有的方式显示。 你可以试试:

    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
    

    这很丑陋,但它可以解决问题..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多