SQL 过滤器不适用于去年
SQL Filter doesn't work with past year
我遇到了一个很奇怪的问题。
当我过滤当年的数据时,一切正常:
但是,如果我尝试倒退一年,突然间我得到一份空白报告……
进入下一年不是问题,就像您在这里看到的那样:
我的代码是:
These 2 values come through as a 'date' in a private sub
datumvan = DateTimePickerVan.Value.ToLocalTime
datumtot = DateTimePickerTot.Value.ToLocalTime
Dim culture As New CultureInfo("pt-BR")
sqlstr = "SELECT * FROM [Geschiedenis$] WHERE Aangemeld BETWEEN '" & datumvan.ToString("d", culture) & "' AND '" & datumtot.ToString("d", culture) & "'"
另请参阅 sql 进行调试时的样子:
总而言之:一切正常,除非我去上一年。
如果我放置:NOT BETWEEN,一切都颠倒了,我看到了所有数据。
我也尝试用 >= 和 <= 替换 BETWEEN,但同样的事情发生了。
有什么想法吗?
Aangemeld 显然是一个日期,它应该是。因此,您必须将 Aangemeld 与日期进行比较。为此,
- 首先将日期转换为 VB 中的字符串。使其成为特定的日期格式,而不是依赖于某些区域设置。例如。
datumvan.ToString("dd/MM/yyyy")
- 然后将字符串转换为 SQL 中的日期。再次不要依赖数据库设置,而是命名您正在使用的格式。
如何在 SQL 中将字符串转换为日期取决于您使用的 DBMS。以下是一些示例:
MySQL:
" ... WHERE Aangemeld BETWEEN STR_TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','%d/%m/%Y') AND ... "
SQL_Server:
" ... WHERE Aangemeld BETWEEN CONVERT(datetime,'" & datumvan.ToString("dd/MM/yyyy") & "',103) AND ... "
甲骨文:
" ... WHERE Aangemeld BETWEEN TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','dd/mm/yyyy') AND ... "
许多 DBMS(例如 MySQL、SQL-Server 和 PostgreSQL)也接受 ISO 格式的字符串作为日期文字。
" ... WHERE Aangemeld BETWEEN '" & datumvan.ToString("yyyyMMdd") & "' AND ... "
在 Oracle 中,这样的文字必须以 DATE 开头:
" ... WHERE Aangemeld BETWEEN DATE'" & datumvan.ToString("yyyyMMdd") & "' AND ... "
还有一件事:我不知道其他 DBMS 是否也是这种情况,但我知道 Oracle 将没有时间的日期视为午夜日期,因为它只知道 datetime 数据类型。所以 between 子句将排除最后一天。这就是为什么在 Oracle 中您会比较 TRUNC(Aangemeld) 而不是 Aangemeld。
我遇到了一个很奇怪的问题。
当我过滤当年的数据时,一切正常:
进入下一年不是问题,就像您在这里看到的那样:
我的代码是:
These 2 values come through as a 'date' in a private sub
datumvan = DateTimePickerVan.Value.ToLocalTime
datumtot = DateTimePickerTot.Value.ToLocalTime
Dim culture As New CultureInfo("pt-BR")
sqlstr = "SELECT * FROM [Geschiedenis$] WHERE Aangemeld BETWEEN '" & datumvan.ToString("d", culture) & "' AND '" & datumtot.ToString("d", culture) & "'"
另请参阅 sql 进行调试时的样子:
总而言之:一切正常,除非我去上一年。 如果我放置:NOT BETWEEN,一切都颠倒了,我看到了所有数据。
我也尝试用 >= 和 <= 替换 BETWEEN,但同样的事情发生了。
有什么想法吗?
Aangemeld 显然是一个日期,它应该是。因此,您必须将 Aangemeld 与日期进行比较。为此,
- 首先将日期转换为 VB 中的字符串。使其成为特定的日期格式,而不是依赖于某些区域设置。例如。
datumvan.ToString("dd/MM/yyyy")
- 然后将字符串转换为 SQL 中的日期。再次不要依赖数据库设置,而是命名您正在使用的格式。
如何在 SQL 中将字符串转换为日期取决于您使用的 DBMS。以下是一些示例:
MySQL:
" ... WHERE Aangemeld BETWEEN STR_TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','%d/%m/%Y') AND ... "
SQL_Server:
" ... WHERE Aangemeld BETWEEN CONVERT(datetime,'" & datumvan.ToString("dd/MM/yyyy") & "',103) AND ... "
甲骨文:
" ... WHERE Aangemeld BETWEEN TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','dd/mm/yyyy') AND ... "
许多 DBMS(例如 MySQL、SQL-Server 和 PostgreSQL)也接受 ISO 格式的字符串作为日期文字。
" ... WHERE Aangemeld BETWEEN '" & datumvan.ToString("yyyyMMdd") & "' AND ... "
在 Oracle 中,这样的文字必须以 DATE 开头:
" ... WHERE Aangemeld BETWEEN DATE'" & datumvan.ToString("yyyyMMdd") & "' AND ... "
还有一件事:我不知道其他 DBMS 是否也是这种情况,但我知道 Oracle 将没有时间的日期视为午夜日期,因为它只知道 datetime 数据类型。所以 between 子句将排除最后一天。这就是为什么在 Oracle 中您会比较 TRUNC(Aangemeld) 而不是 Aangemeld。