Oracle SQL中的java.sql.Timestamp到Date转换

时间:2018-05-19 10:27:07

标签: java sql oracle11g sql-date-functions sql-timestamp

我在Oracle SQL中遇到了这个奇怪的时间戳到日期转换问题。

这是SQL语句:

String INSERT_SQL = String.format("INSERT INTO AUDIT_TASK (%s, %s, %s, %s) VALUES (AUDIT_TASK_SEQ.nextval,?,?,?)",ID,CLASS_NAME,TASK_STEP_TIMESTAMP,OPERATOR);

java.util.Calendar utcCalendarInstance = Calendar.getInstance(TimeZone .getTimeZone("UTC"));
java.util.Calendar cal = Calendar.getInstance();
final PreparedStatement stmt = con.prepareStatement(INSERT_SQL);
stmt.setString(1, audit.getClassName().getValue());
// Save the timestamp in UTC
stmt.setTimestamp(2,new Timestamp(cal.getTimeInMillis()), utcCalendarInstance);

当我执行此语句时,虽然在大多数情况下creation_date和task_step_timestamp的日期相同,但有时我得到的task_step_timestamp是由一些虚假日期生成的 - 如'25 -APR-0000'或'00 -Jan-0001'等

  • ID | Creation_date | Task_step_timestamp
  • 1 | 27-APR-2018 17:58:53 | 25-APR-0000 09:00:45
  • 2 | 27-APR-2018 18:06:25 | 00-Jan-0001 09:18:25

Oracle DB中task_step_timestamp列的数据类型为“DATE”。

有人可以建议将时间戳转换为日期不一致的原因吗?

1 个答案:

答案 0 :(得分:0)

我不明白为什么你在这里使用String#format。只需使用提到明确列的常规插入:

String INSERT_SQL = "INSERT INTO AUDIT_TASK (ID, ERROR_MESSAGE, TASK_STEP_TIMESTAMP, OPERATOR) ";
INSERT_SQL += "VALUES (AUDIT_TASK_SEQ.nextval, ?, ?, ?)";
PreparedStatement stmt = con.prepareStatement(INSERT_SQL);

然后绑定你的值:

stmt.setString(1, audit.getErrorMessage() != null ? audit.getErrorMessage().getValue() : null);
stmt.setTimestamp(2, new Timestamp(cal.getTimeInMillis()), utcCalendarInstance);
stmt.setString(3, audit.getClassName().getValue());

请注意,占位符按从左到右的顺序用于错误消息,任务步骤时间戳和操作符。您的原始代码似乎无法按顺序绑定参数。通过使用明确提到列的insert语句,您可以避免此问题。

修改

对我来说,为什么你担心时间戳的时区也没有意义。只需获取自纪元以来的毫秒数,然后让数据库将其存储为UTC:

Timestamp timestamp = new Timestamp(System.currentTimeMillis());
stmt.setTimestamp(2, timestamp);