我在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'等
Oracle DB中task_step_timestamp列的数据类型为“DATE”。
有人可以建议将时间戳转换为日期不一致的原因吗?
答案 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);