Ошибка «Изображение формата даты заканчивается ..» при выполнении выбора через JDBC PreparedStatement

Работа с базой данных Oracle. Он имеет столбец с типом DATE и оператор select (здесь упрощено для удобства чтения), выданный через JDBC PreparedStatement, выглядит следующим образом:

select  DATE1 from TYPE_TABLE  where TYPE_TABLE.DATE1 =  ?

Значение параметра вопросительного знака во время выполнения - 2018-01-31 12:50:30.0 PST. Мы устанавливаем параметр через setTimeStamp API класса PreparedStatement. Ошибка, которую мы видим при выполнении вышеуказанного запроса выбора, выглядит следующим образом:

java.sql.SQLDataException: ORA-01830: date format picture ends before 
converting entire input string 

Я провел поиск по SO и другим дочерним сайтам сети SE, и все ссылки, которые я нашел, связаны с вставкой дат в базу данных без использования маски правильного формата. Но я еще не нашел ничего, связанного с операторами select.

В чем здесь может быть возможная проблема и решение?

P.S: тип столбца DATE1 действительно имеет тип DATE в базе данных Oracle.

Обновлено: если проблема заключается в параметре NLS_DATE_FORMAT, то какой формат следует использовать для рассматриваемого значения даты (например, 2018-01-31 12:50:30.0 PST) здесь?

Пожалуйста, не просто описывайте свой код. Опубликуйте это.

JB Nizet 11.03.2018 17:51

@JBNizet, мы используем стандартный синтаксис JDBC ... Что-нибудь особенное, что, по вашему мнению, я должен здесь размещать?

Inquisitive 11.03.2018 18:04

Все, что вы думаете, актуально. Возможно, вы не заметили глупую ошибку в коде. Если вы его не покажете, мы не сможем найти его для вас.

JB Nizet 11.03.2018 18:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
124
3

Ответы 3

Oracle хранит дату, используя 7 байтов. По одному байту для века, года, месяца, дня, часов, минут и секунд. Таким образом, любая строка должна быть передана с соответствующей строкой формата, чтобы указать, как каждый компонент этой строки будет анализироваться в 7-байтовой дате.

select DATE1 
  from TYPE_TABLE  
 where TYPE_TABLE.DATE1 = to_date('2018-01-31 12:50:30', 'yyyy-mm-dd hh24:mi:ss');

Если формат не указан, Oracle использует формат по умолчанию, доступный в параметре NLS_DATE_FORMAT. Если формат по умолчанию не соответствует используемой строке, мы получаем эту ошибку:

ORA-01830: date format picture ends before  converting entire input string

JDBC должен позаботиться о преобразовании. Если вы сделаете это вручную, вы рискуете несоответствие для разных сред i18n.

fhossfel 11.03.2018 17:58

@ArtBajji Вы думаете, что при вводе дат в БД не был указан правильный формат? Каким должен быть NLS_DATE_FORMAT для значения даты, указанного в вопросе? т.е. 2018-01-31 12:50:30.0 PST

Inquisitive 11.03.2018 18:09

Я не профессионал в области Java. Я разработчик базы данных. Со стороны базы данных формат, используемый java, и строка даты не совпадают для синтаксического анализа семи частей данных на предмет даты. NLS_DATE_FORMAT изменять не нужно. Правильный формат должен использоваться java.

ArtBajji 11.03.2018 18:28

Также обратите внимание, что отметка времени и дата - это два разных типа данных в Oracle. Дата хранит данные с точностью до секунд. Метка времени хранит данные с точностью до 9-й десятичной дроби секунды, что составляет максимум 11 байт.

ArtBajji 11.03.2018 18:31

Если рассматриваемый столбец имеет тип данных DATE, используйте функцию, которая преобразует вашу строку в DATE, а не TIMESTAMP.

ArtBajji 11.03.2018 18:32

Справедливо предположить, что ваш драйвер JDBC преобразует тип данных Oracle в тип java.sql.TimeStamp или java.sql.Date (и обратите внимание, что есть различия между java.util.Date и java.sql.Date в терминах точности например). В случае, например, типа java.sql.Timestamp попробуйте указать:

ret.value = java.sql.Timestamp(java.util.Date().getTime()); copy to clipboard
and see if this helps. Then you will be able to use:
ret.value = java.sql.Timestamp(system.parseDate(work.getString("yourDate"), 
    "yyyyMMddHHmmssz").getTime()); 

К вашему сведению… Классы java.sql.Timestamp и java.sql.Date теперь являются наследие, замененные классами java.time начиная с JDBC 4.2 и более поздних версий.

Basil Bourque 12.03.2018 01:16

Oracle не совместим с SQL: тип данных DATE содержит часы, минуты и секунды.

В документации говорится:

This datatype contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND. It does not have fractional seconds or a time zone.

Отметка времени должна быть необходима только в том случае, если вы опускаетесь до доли секунды и / или хотите сохранить информацию о часовом поясе.

Может с setDate () попробовать?

Другие вопросы по теме