Access 2007:查询两个短日期值之间的DateTime字段

时间:2009-10-07 14:41:27

标签: sql database ms-access ms-access-2007

我有一个包含两个用于用户输入的文本框的表单。两个文本框都将属性格式设置为“短日期”。一个是“开始日期”,另一个是“结束日期”。我还有几个表,每个表都有一个DateTime字段(“studystartdatetime”)。我希望能够查询这些表,但将结果限制为DateTime字段在输入日期(包括)之间的行。目前,条件是:

WHERE s.studystartdatetime BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate

但是,这不会返回在指定的enddate上发生的行。

我已经尝试了我能想到的CDate,Format和DateValue的每个组合来包装一个或所有这些字段,但我总是收到同样的神秘错误:

  

表达式输入错误,或者太复杂而无法评估。例如,数字表达式可能包含太多复杂元素。尝试通过将表达式的一部分分配给变量来简化表达式。

我尝试过的一些条件示例:

WHERE CDate(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate

WHERE DateValue(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate

WHERE CDate(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN CDate(Format(forms!frmMain!txtstartdate, "yyyy/mm/dd")) AND CDate(Format(forms!frmmain!txtenddate, "yyyy/mm/dd"))

WHERE DateValue(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN CDate(Format(forms!frmMain!txtstartdate, "yyyy/mm/dd")) AND CDate(Format(forms!frmmain!txtenddate, "yyyy/mm/dd"))

WHERE DateValue(Format(s.studystartdatetime, "Short Date")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate

对此的任何输入都将非常感激:)

2 个答案:

答案 0 :(得分:2)

正在发生的事情是您的短日期输入在用户输入的那天开始的午夜产生日期时间值。所以,2009-1-1到2009-1-10的范围(或者你的系统上使用的任何短日期格式)都是搜索从1月1日开始到非常开始的事件。 1月10日,不包括1月10日晚些时候发生的事件。

要更正,请将1添加到用户放入搜索的结束日期。这将从1月1日开始到1月11日开始搜索,包括1月10日的所有活动。

最后,1月11日午夜时间发生的事件可能会以这种方式传入您的结果,因此您应该使用

而不是使用BETWEEN

studystartdatetime> =表格!frmMain!txtStartDate AND studystartdatetime<形式!frmMain!txtEndDate + 1

答案 1 :(得分:0)

拉里的答案对你来说是正确答案,但让我提出一些问题。

  1. 您需要区分日期格式和日期存储。在Jet / ACE数据库引擎(Access的默认数据库引擎)中,日期存储为当天的整数和时间的小数部分。这就是为什么你可以在日期中添加一个数字(或十进制)并获得正确的结果,因为日期的基础表示的整数部分代表自1899年12月30日以来的日子(之所以不是Dec的原因)第31个是复杂的 - 有人搞砸了闰年,所以一大堆程序用错误的假设写成,关于1899年12月31日的实际情况。)

  2. “短日期”是日期格式,标准m / d / yy(或m / d / yyyy,具体取决于Windows和Access中的本地设置)。它与存储在表中的实际基础日期值无关,但如果使用格式化结果,则会产生巨大影响。例如,Format(Date(),“m / d / yyyy”)返回一个字符串,而不是日期值。它是一个可以隐式强制转换为日期值的字符串,并且通常依赖于透明的情况。但是你仍然需要理解Format()函数返回一个字符串,并且该字符串不会总是被视为日期。

  3. Jet / ACE SQL期望格式化日期以美国顺序传递,反直觉m / d / yyyy,而不是更符合逻辑的d / m / yyyy,或者更好的是,ISO标准yyyy /米/ d。因此,只要您使用针对Windows设置的非美国语言环境运行应用程序,就需要明确说明日期。这意味着将日期转换为非模糊格式(d / mmm / yyyy可用,因为它以数字和月份为单位指定日期),或使用DateSerial()函数处理所有日期。这适用于WHERE子句中的日期条件,或者您正在进行日期计算的SELECT语句中的任何位置 - 以非模糊格式或使用DateSerial()将日期传递给函数,您将避免此问题。