【发布时间】:2018-03-23 16:20:51
【问题描述】:
我正在尝试使用开始日期和结束日期作为参数运行查询,这可能为空。
MySQL - DB 或 JDBC 驱动程序或组合 - 无法处理空值,我的意思是,SQL AND endDate <= null 排除每一行。
所以我尝试使用startDate >= LocalDate.MIN,它适用于“无开始日期”。
但是endDate <= LocalDate.MAX 不允许任何日期。这是 SQL 模板:
String strStmt = "SELECT d.forecastId, d.valueDate, d.value " +
"FROM data d " +
"WHERE d.forecastId = ? " +
"AND valueDate >= ? " +
"AND valueDate <= ? " +
这是变量分配:
if (startDate == null) {
statement.setObject(2, LocalDate.MIN);
} else {
statement.setObject(2, startDate.toInstant().atZone(
ZoneId.systemDefault()).toLocalDate());
}
if (endDate == null) {
statement.setObject(3, LocalDate.MAX);
} else {
statement.setObject(3, endDate.toInstant().atZone(
ZoneId.systemDefault()).toLocalDate());
}
try (ResultSet rs = statement.executeQuery()) {
...
这是它生成的 SQL(通过 P6Spy):
SELECT valueDate FROM data d WHERE d.forecastId = 52010
AND valueDate >= '-999999999-01-01'
AND valueDate <= '+999999999-12-31'
这不起作用,我没有行。
如果我再把它改成不那么极端的东西:
if (endDate == null) {
statement.setObject(3, LocalDate.parse("2019-01-01"));
...
我在 P6Spy 日志中看到以下内容:
SELECT valueDate FROM data d WHERE d.forecastId = 52010
AND valueDate >= '-999999999-01-01'
AND valueDate <= '2019-01-01'
并且查询工作正常,当然在将来的某个时候除外。
这是 MySQL 中的某种溢出吗?我应该以不同的方式使用LocalDate.MAX,还是可以使用什么来代替LocalDate.MAX?
我不想回到
statement.setDate(3, new java.sql.Date(Long.MAX_VALUE);
产生以下内容:
AND valueDate <= '17-Aug-94'
哪个也不起作用 - 也许是 Y2K 或 2038 年的错误? P6Spy 以自己无用的格式显示它并没有帮助。
【问题讨论】:
-
您能否更改查询本身,即如果日期不为空,则仅动态包含其他日期比较?
-
阅读文档? 支持的范围是 '1000-01-01' 到 '9999-12-31'。 mariadb.com/kb/en/library/date
-
与您的问题无关,但Connector/J 6.0.4是Connector/J废弃版本6的开发版本,不是生产就绪版本。最后发布的版本是 5.1.44。最新的开发版本是 8.0.8(但该版本还没有生产就绪!)。
-
@MarkRotteveel 哦,对了。我刚刚抓住了 6.0.6,因为 IntelliJ 在 pom.xml 中自动完成了它。我在 mysql bugzilla 中同时遇到了字符编码和相关 bug 的其他问题,所以我尝试对其进行更改,但 IntelliJ 似乎坚持使用它的 jar 来等待严峻的死亡,这使得更改版本变得乏味。我现在正在试用 mariadb connector/j 2.1.2