【问题标题】:Query using setDate does not find results - cannot see final-query with parameters使用 setDate 查询未找到结果 - 无法看到带参数的最终查询
【发布时间】:2015-11-08 11:51:09
【问题描述】:

我有一个 SQL,它查看维度表(存储 2020 年之前的每个日期),然后检索今天的行。 我看着桌子,今天的日期在那里。 问题是,SQL 没有返回任何结果。

我在想一个与使用 java.sql.PreparedStatement.setDate 方法有关的问题。 过去我认为这工作正常,现在我做了一些回归测试,但它失败了。与过去的不同之处在于现在使用 Oracle 12 DB 而不是过去的 11,并在 CentOS 6.5 而不是 AIX 上运行它。

在搜索中,我在这里找到了这个主题: Using setDate in PreparedStatement

据我所知,我正在按照建议做。

这是java代码和查询:

public static String SELECT_DATUM = "SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME, YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME WHERE DATE = :date";

java.util.Calendar now = Calendar.getInstance();
now.clear(Calendar.HOUR);
now.clear(Calendar.MINUTE);
now.clear(Calendar.SECOND);
now.clear(Calendar.MILLISECOND);

Date tmpDate = now.getTime();

Date tmpDate2 = new Date(((java.util.Date)tmpDate ).getTime());

statement.setDate(1, tmpDate2 );

我注意到 getTime() 被调用了两次。但我不认为它那么糟糕。 我还注意到一些显示格式: 在数据库中,日期列向我显示这样的日期:'08.11.2015' 在调试 tmpDate2 时在 java 中显示这样的日期:'2015-11-08' 在调试 tmpDate 时在 java 中向我显示了这样的日期 'Sun Nov 08 12:00:00 CET 2015'

但同样,这些只是显示格式,而它是背景中的日期对象和数据库中的日期类型。我希望 je JDBC 驱动程序会在没有格式的情况下映射它本身,这就是我们使用 setDate 方法而不是 setString 的原因。

我做错了什么?我可以做些什么来进一步调试以获得它? 我希望看到最终使用参数执行的 SQL 查询。

我在 db istance 上试过这个 sql:

SELECT * FROM v$sql s WHERE s.sql_text LIKE '%select time%' ;

但只有这样:“... where date = trunc(:1 )” 在这一行上,至少我可以看到它使用了我期望它使用的正确模式,并且我在哪里检查了今天的日期是否可用。

编辑: 我发现了一些东西: 我看到另一个代码使用相同的函数,但给出的是 GregorianCalendar 而不是 Calendar。使用时 新的格雷戈里安卡兰达(); 代替 日历.getInstance(); 没有区别。 但是当我分配一个日期并且不让系统采用当前时间时,它就可以工作: 使用 新的公历(2015,Calendar.NOVEMBER,8); 将从 SQL 中检索我想要的行。

【问题讨论】:

  • 试试这个:SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME, YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME WHERE DATE = TRUNC (:date)
  • 你使用java.sql.Date吗?
  • new Date(((java.util.Date)tmpDate ).getTime()); tmpDate is java.util.Date new Date 创建 java.sql.Date
  • new Date(((java.util.Date)tmpDate ).getTime()); tmpDate is java.util.Date new Date 创建 java.sql.Date statement.setDate(1, tmpDate2 );语句是 PreparedStatement 并且 setDates 在这种情况下采用 java.sql.Date
  • 你可能想要:WHERE trunc(DATE) = :date(顺便说一句:date 是一个列的可怕名称)

标签: java sql oracle date prepared-statement


【解决方案1】:

Zsigmond Lőrinczy 将此答案发布为评论:

试试这个:SELECT TIME_ID、DATE、DAY_NAME、WEEK_NAME、MONTH_NAME、 YEAR_NAME、SORTING、RELATIONDATE、VALID_TO、VALID_FROM FROM DIM_TIME WHERE DATE = TRUNC (:date) – 3 小时前

这适用于我的问题。

如果他不打算写自己的回复(以获得声誉点数),我写这篇文章是为了稍后检查它作为这个问题的答案。

但我想知道如何通过在 java 上进行准备来获得相同的结果。 该代码使用 clear-methods,它被释放到一个名为“trunc”的自己的方法中。我认为程序员打算这样做而不是 SQL 中的 TRUNC。我想知道在java中是否可以这样做,如果可以,怎么做?

编辑: 我想知道为什么根本需要 TRUNC。因为数据库中的列是日期类型而不是时间戳。那么不会有自动截断吗?我会期待这个。为什么我需要 trunc on SQL?

【讨论】:

  • "为什么我需要在 SQL 上截断" - 因为在 Oracle 中 DATE 还包含一个时间:docs.oracle.com/cd/E11882_01/server.112/e41084/…
  • 在这个文档上:docs.oracle.com/cd/E11882_01/java.112/e16548/… 我发现:这是因为如果你使用 setDate 方法,那么 Oracle DATE 数据的时间部分将会丢失,如果你使用 setTimestamp 方法,那么将不使用 DATE 列上的索引。 Oracle 12 中是否发生了这种变化?
  • 但是数据库中存储的值可能包含一个时间
  • 但是 TRUNC() 会起作用,因为时间部分被截断了。如果在数据库中有一个带时间的值,那么如果没有(因为它被截断)时间,我就不会匹配该值。
  • trunc() 不会“删除”时间,它只是将其设置为 00:00:00
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 2015-09-07
  • 2021-03-03
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多