代码之家  ›  专栏  ›  技术社区  ›  Paul Williams

dataTable.select在空日期时间列上使用isNull运算符时行为异常

  •  0
  • Paul Williams  · 技术社区  · 15 年前

    我有一个带有日期时间列“datecol”的数据表,它可以是dbnull。数据表中有一行的该列中有一个空值。

    我正在尝试查询在此列中有dbnull值或日期大于今天日期的行。今天是2010年11月5日。我构建了一个查询来选择所需的行,但它没有按预期工作。查询是:

    string query = "ISNULL(DateCol, '" + DateTime.MaxValue + "'") > "' + DateTime.Today "'"
    

    这将导致以下查询:

    "ISNULL(DateCol, '12/31/9999 11:59:59 PM') > '5/11/2010'"
    

    当我运行这个查询时,没有得到任何结果。我花了一段时间才弄明白原因。下面是我在Visual Studio即时窗口中的调查:

    > dt.Rows.Count
    1
    > dt.Rows[0]["DateCol"]
    {}
    > dt.Rows[0]["DateCol"] == DBNull.Value
    true
    > dt.Select("ISNULL(DateCol,'12/31/9999 11:59:59 PM') > '5/11/2010'").Length
    0  <-- I expected 1
    

    试验和错误显示在以下边界处的日期检查存在差异:

    > dt.Select("ISNULL(DateCol, '12/31/9999 11:59:59 PM') > '2/1/2000'").Length
    0
    > dt.Select("ISNULL(DateCol, '12/31/9999 11:59:59 PM') > '1/31/2000'").Length
    1 <-- this was the expected answer
    

    如果用而不是引号将datetime字段括起来,则查询工作正常。

    > dt.Select("ISNULL(DateCol, #12/31/9999#) > #5/11/2010#").Length
    1
    

    我的机器的区域设置当前设置为en-us,短日期格式为m/d/yyyy。

    为什么原始查询返回了错误的结果?

    如果将日期与2000年1月31日进行比较,而不是与2000年2月1日进行比较,为什么它会工作得很好?

    1 回复  |  直到 15 年前
        1
  •  4
  •   Eric Rosenberger    15 年前

    查询表达式格式使用…表示日期时间值。单引号用于字符串值。在使用单引号括住日期时间的表达式中,它执行字符串比较,其中“12/31/9999”中的字符“1”位于“5/11/2010”中的“5”之前,“2/1/2000”中的“2”之前,而不是Unicode顺序的“1/31/2000”中的“1”。