【问题标题】:SQL Filter doesn't work with past yearSQL 筛选器不适用于过去一年
【发布时间】:2015-01-08 14:21:48
【问题描述】:

我遇到了一个很奇怪的问题。

当我过滤当年的数据时,一切正常: 但是如果我想回到一年前,突然我得到一个空白的报告......

去明年不是问题,就像你在这里看到的那样:

我的代码是:

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,一切都颠倒过来,我会看到所有数据。

我也尝试用 >= 和

有什么想法吗?

【问题讨论】:

  • 听起来您的日期参数顺序错误。较早的日期需要作为第一个参数,较晚的日期需要作为第二个参数。停止 sql 字符串行上的调试器并查看日期参数的值。
  • 在我看来,您将日期数据存储或视为字符串。如果是这样,你不能指望它像约会一样。
  • Tab Alleman:我更新了我的帖子,所以你可以看到 sql 字符串并且日期在正确的位置。 Plutonix:那么,为了将日期以 dd/mm/yyyy 格式作为日期,我需要进行哪些更改?
  • 刻度和 .ToString 将日期(值类型)转换为文本/字符串。 “3”和“0”之间没有任何内容,因为“3”在 TEXT COMPARE 中的计算结果大于“0”。如果 dbCols 是 Date 类型,请去掉刻度和 .ToString()
  • 如果您直接对您的数据库运行查询 - 使用上一年的连接字符串,您会得到结果吗?

标签: sql vb.net filtering


【解决方案1】:

Aangemeld 显然是一个约会,它应该是。因此,您必须将 Angemeld 与日期进行比较。为此,

  • 首先在 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。

【讨论】:

  • 感谢所有帮助。我终于能够让它工作了。根据您的所有提示以及页面:stackoverflow.com/questions/25058768/… 我的主要问题如下:您应该始终使用不明确的日期格式。当您的日期格式为 00/00/0000 时,Access 必须猜测是 dd/mm/yyyy(英国)还是 mm/dd/yyyy(美国)。解决此问题的最简单方法是以 ISO 格式 (yyyymmdd) 提供您的日期或将月份提供为一个简短的单词 (dd mmm yyyy hh:mm:ss - 例如 2014 年 8 月 1 日 06:00:00)
  • ISO 格式很好,月份名称缩写不是,因为您再次依赖区域设置(December 是 12 月的“Dec”或 Dezember 的“Dez”或 Diciembre 的“Dic”或任何其他地区名称)。
  • 嗯,这才是真正的托尔斯滕。但我不喜欢我的 datagridview 中的 ISO 格式,所以在我查询之后,我会将输出再次格式化为像 mm/dd/yyyy 这样的日期。再次感谢
  • 输出?它是 WHERE 子句,您可以在其中比较值并需要可靠的格式。在您的 SELECT 子句中,您可以使用任何其他格式或根本不设置格式。您的查询显示SELECT *。你改了吗?
  • 谢谢!我不知道我能做到这一点。现在一切都在使用 "SELECT ..., FORMAT(Aangemeld, 'dd/MM/yyyy-hh:mm:ss') FROM ... 感谢 Thorsten 的所有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多