数据库日期/时间比较未产生预期结果?

Posted

技术标签:

【中文标题】数据库日期/时间比较未产生预期结果?【英文标题】:Database Date/Time comparison does not yield expected result? 【发布时间】:2015-01-03 17:49:34 【问题描述】:

我在使用 C# 和 MS Access 时遇到问题,我希望以下调用返回一条记录:

   c = Shift.Get(ProfileID, Start, null, null, null, null, null, null);

其中 Start 为“1/7/2015 3:30:00 PM”,ProfileID 为“******16732”,方法为:

   public static ObservableCollection<Shift> Get(string profileID, DateTime? start,
         DateTime? stop, string fullName, bool? closed, bool? archived = null,
         Database db = null, string sort="ASC")
    
        OleDbCommand cmd = new OleDbCommand(
            "SELECT profiles.profile_id, profiles.full_name, shifts.start, " +
            "shifts.stop, shifts.start_log, shifts.stop_log, shifts.notes, " +
            "shifts.closed, shifts.archived FROM shifts, profiles WHERE " +
            (profileID != null ? "(shifts.profile_id=@profile_id) AND " : "") +
            (start.HasValue ? "(shifts.start>=@start) AND " : "") +
            (stop.HasValue ? "(shifts.stop<=@stop) AND " : "") +
            (fullName != null ? "profiles.full_name=@full_name AND " : "") +
            (closed.HasValue ? "shifts.closed=@closed AND " : "") +
            (archived.HasValue ? "shifts.archived=@archived AND " : "") +
            "(shifts.profile_id=profiles.profile_id) " +
            "ORDER BY shifts.start " + sort 
            );

        if (profileID != null)
            cmd.Parameters.AddWithValue("@profile_id", profileID);

        if (start.HasValue)
            cmd.Parameters.AddWithValue("@start", start.Value.ToString());

        if (stop.HasValue)
            cmd.Parameters.AddWithValue("@stop", stop.Value.ToString());

        if (fullName != null)
            cmd.Parameters.AddWithValue("@full_name", fullName);

        if (closed.HasValue)
            cmd.Parameters.AddWithValue("@closed", closed.Value);

        if (archived.HasValue)
            cmd.Parameters.AddWithValue("@archived", archived.Value);
        ....
        

给定以下班次表:

profile_id  start               stop                    start_log           stop_log                notes   closed  archived
******45544 1/7/2015 3:30:00 PM 1/2/2015 11:30:00 PM    1/7/2015 3:06:02 PM 1/2/2015 11:32:40 PM    ""  Yes No
******12956 1/7/2015 3:30:00 PM 1/2/2015 9:00:00 PM     1/7/2015 3:08:10 PM 1/2/2015 9:15:29 PM   ""    Yes No
******17392 1/7/2015 2:00:00 PM 1/2/2015 11:30:00 PM    1/7/2015 1:46:07 PM 1/2/2015 11:33:09 PM    ""  Yes No
******16732 1/7/2015 3:30:00 PM 1/2/2015 6:30:00 PM     1/7/2015 3:08:38 PM 1/2/2015 6:35:03 PM   ""    Yes No
******15503 1/7/2015 2:00:00 PM 1/2/2015 10:00:00 PM    1/7/2015 1:46:43 PM 1/2/2015 10:01:24 PM    ""  Yes No
******14536 1/7/2015 3:30:00 PM 1/2/2015 11:30:00 PM    1/7/2015 3:04:12 PM 1/2/2015 11:35:19 PM    ""  Yes No

但是,我得到的回报是没有记录,也没有错误。这很令人惊讶,因为我在 SQL 语句的 WHERE 子句中确实有一个shifts.start &gt;= @start,并且数据存在。

注意,ProfileID被混淆了,因为它是敏感的,并且开始日期在停止日期之后开始,这显然是错误的,但那是测试数据,应该与结果无关。如果未提供 db,则存在默认数据库连接。

我必须进行一些编辑,希望我没有在任何地方打错字。

有什么线索吗?

【问题讨论】:

添加参数的时候为什么要把日期转成字符串? 在 msaccess 中使用 datetime 查询时,您需要将日期放在 # 符号内,如下所示: where date =#07/01/2015 03:30:00# @MarkPM 没有特别的原因,但我看到不调用ToString() 也可以,并且可能是首选。会改成这个。 @TomerKlein 使用参数化查询添加井号会导致 OleDBException。 如果您从中删除 .ToString() 它应该可以工作 @MarkPM 我已经删除了 ToString() 并且它工作得很好。我想知道它是在内部调用 ToString() 还是“它”识别 DateTime 并自动获取正确的日期格式,而与本地无关? 【参考方案1】:

您需要将 DateTime 作为 DateTime 对象而不是字符串传递(删除 .ToString()。 这样,该命令将正确解析 DateTime 对象,以便 Access 将其识别为 DateTime。

【讨论】:

我应该早点澄清一下,这样做似乎有效并且没有错误,但不返回记录的原始行为仍然存在。 我直接从调试器中将值复制为1/7/2015 3:30:00 PM 所以我相信...... 我认为这不起作用并导致a data type mismatch in criteria expression。不知道为什么它似乎更早起作用,但我确认它不起作用。 班次表是否开始日期时间类型? 是的,MS Access 中shifts 表中的start 列是日期/时间类型。

以上是关于数据库日期/时间比较未产生预期结果?的主要内容,如果未能解决你的问题,请参考以下文章

比较 object.Value = Null 不会产生预期的结果

比较这两个表不会产生预期的结果。我该如何解决?

列表中的元素计数未产生预期结果

Hive 中的左连接未返回预期结果

字符串比较未按预期工作。我想比较两个字符串值,但比较似乎总是给出一个真实的结果

按每周一分组数据未按预期工作