Преобразование временной метки в дату в Oracle SQL - PullRequest
0 голосов
/ 19 мая 2018

Я столкнулся с этой странной проблемой преобразования меток времени в дату в 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-АПР-0000 09: 00: 45
  • 2 | 27-АПР-2018 18: 06: 25 |00-Jan-0001 09: 18: 25

Тип данных столбца task_step_timestamp в БД Oracle - «DATE».

Может кто-нибудь подсказать причину этого несовместимого преобразованияотметка времени на сегодняшний день?

1 Ответ

0 голосов
/ 19 мая 2018

Я не понимаю, почему вы используете 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());

Обратите внимание, что заполнители, в порядке слева направо, относятся к ошибкесообщение, метка времени шага задачи и оператор.Ваш оригинальный код, кажется, связывает параметры не по порядку.Используя оператор вставки, который явно упоминает столбцы, вы можете избежать этой проблемы.

Редактировать:

Мне также не имеет смысла, почему вы беспокоитесьо часовых поясах для вашей временной метки.Просто получите количество миллисекунд с начала эпохи, а затем позвольте базе данных хранить это как UTC:

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