Я получаю исключение (см. Ниже), если пытаюсь сделать
resultset.getString("add_date");
для соединения JDBC с базой данных MySQL, содержащей значение DATETIME 0000-00-00 00:00:00 (квазинулевое значение для DATETIME), хотя я просто пытаюсь получить значение как строку, а не как объект.
Я обошел это, сделав
SELECT CAST(add_date AS CHAR) as add_date
который работает, но кажется глупым ... есть ли лучший способ сделать это?
Я хочу сказать, что мне просто нужна необработанная строка DATETIME, чтобы я мог сам проанализировать ее как есть .
примечание: вот где появляется 0000: (из http://dev.mysql.com/doc/refman/5.0/en/datetime.html )
Недопустимые значения DATETIME, DATE или TIMESTAMP преобразуются в «нулевое» значение соответствующего типа ('0000-00-00 00:00:00' или '0000-00-00').
Конкретным исключением является следующее:
SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
SQLState: S1009
VendorError: 0
java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.ResultSetImpl.getTimestampFromString(ResultSetImpl.java:6343)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5670)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5491)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5531)
Альтернативный ответ, вы можете использовать этот URL-адрес JDBC непосредственно в конфигурации вашего источника данных:
jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull
Редактировать:
Источник: MySQL Manual
Обновление: Александр сообщил об ошибке, влияющей на mysql-connector-5.1.15 в этой функции. Смотрите ИЗМЕНЕНИЯ на официальном сайте .
источник
Это заставляет меня думать, что ваш «обходной путь» - не обходной путь, а фактически единственный способ получить значение из базы данных в вашем коде:
SELECT CAST(add_date AS CHAR) as add_date
Кстати, еще несколько примечаний из документации MySQL:
Ограничения MySQL на недопустимые данные :
Типы даты и времени MySQL 5.x :
источник
DATE_FORMAT(column name, '%Y-%m-%d %T') as dtime
Используйте это, чтобы избежать ошибки. Он возвращает дату в строковом формате, а затем вы можете получить ее в виде строки.
resultset.getString("dtime");
На самом деле это НЕ работает. Даже если вы вызываете getString. Внутренне mysql по-прежнему пытается сначала преобразовать его на сегодняшний день.
источник
Если после добавления строк:
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property> hibernate.connection.zeroDateTimeBehavior=convertToNull <connection-property name="zeroDateTimeBehavior">convertToNull</connection-property>
продолжает быть ошибкой:
Illegal DATETIME, DATE, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00 00:00:00' or '0000-00-00').
найти строки:
1) resultSet.getTime("time"); // time = 00:00:00 2) resultSet.getTimestamp("timestamp"); // timestamp = 00000000000000 3) resultSet.getDate("date"); // date = 0000-00-00 00:00:00
заменить на следующие строки соответственно:
1) Time.valueOf(resultSet.getString("time")); 2) Timestamp.valueOf(resultSet.getString("timestamp")); 3) Date.valueOf(resultSet.getString("date"));
источник
Я боролся с этой проблемой и реализовал решения convertToNull, описанные выше. Он работал в моем локальном экземпляре MySql. Но когда я развернул приложение Play / Scala на Heroku, оно перестало работать. Heroku также объединяет несколько аргументов с URL-адресом базы данных, который они предоставляют пользователям, и это решение из-за того, что Heroku использует объединение "?" перед собственным набором аргументов работать не будет. Однако я нашел другое решение, которое, похоже, работает одинаково хорошо.
УСТАНОВИТЬ sql_mode = 'NO_ZERO_DATE';
Я поместил это в свои описания таблиц, и это решило проблему: '0000-00-00 00:00:00' не может быть представлен как java.sql.Timestamp
источник
Я предлагаю вам использовать null для представления нулевого значения.
Какое исключение вы получите?
Кстати:
Нет года, называемого 0 или 0000 (хотя в некоторых датах допускается этот год)
И нет 0-го месяца в году или 0-го дня месяца. (Что может быть причиной вашей проблемы)
источник
Я решил проблему, считая, что «00 -00 -...» не является допустимой датой, затем я изменил определение столбца SQL, добавив выражение «NULL», чтобы разрешить нулевые значения:
SELECT "-- Tabla item_pedido"; CREATE TABLE item_pedido ( id INTEGER AUTO_INCREMENT PRIMARY KEY, id_pedido INTEGER, id_item_carta INTEGER, observacion VARCHAR(64), fecha_estimada TIMESTAMP, fecha_entrega TIMESTAMP NULL, // HERE IS!!.. NULL = DELIVERY DATE NOT SET YET CONSTRAINT fk_item_pedido_id_pedido FOREIGN KEY (id_pedido) REFERENCES pedido(id),...
Затем я должен иметь возможность вставлять значения NULL, что означает «Я еще не зарегистрировал эту временную метку» ...
SELECT "++ INSERT item_pedido"; INSERT INTO item_pedido VALUES (01, 01, 01, 'Ninguna', ADDDATE(@HOY, INTERVAL 5 MINUTE), NULL), (02, 01, 02, 'Ninguna', ADDDATE(@HOY, INTERVAL 3 MINUTE), NULL),...
Таблица выглядит так:
mysql> select * from item_pedido; +----+-----------+---------------+-------------+---------------------+---------------------+ | id | id_pedido | id_item_carta | observacion | fecha_estimada | fecha_entrega | +----+-----------+---------------+-------------+---------------------+---------------------+ | 1 | 1 | 1 | Ninguna | 2013-05-19 15:09:48 | NULL | | 2 | 1 | 2 | Ninguna | 2013-05-19 15:07:48 | NULL | | 3 | 1 | 3 | Ninguna | 2013-05-19 15:24:48 | NULL | | 4 | 1 | 6 | Ninguna | 2013-05-19 15:06:48 | NULL | | 5 | 2 | 4 | Suave | 2013-05-19 15:07:48 | 2013-05-19 15:09:48 | | 6 | 2 | 5 | Seco | 2013-05-19 15:07:48 | 2013-05-19 15:12:48 | | 7 | 3 | 5 | Con Mayo | 2013-05-19 14:54:48 | NULL | | 8 | 3 | 6 | Bilz | 2013-05-19 14:57:48 | NULL | +----+-----------+---------------+-------------+---------------------+---------------------+ 8 rows in set (0.00 sec)
Наконец: JPA в действии:
@Stateless @LocalBean public class PedidosServices { @PersistenceContext(unitName="vagonpubPU") private EntityManager em; private Logger log = Logger.getLogger(PedidosServices.class.getName()); @SuppressWarnings("unchecked") public List<ItemPedido> obtenerPedidosRetrasados() { log.info("Obteniendo listado de pedidos retrasados"); Query qry = em.createQuery("SELECT ip FROM ItemPedido ip, Pedido p WHERE" + " ip.fechaEntrega=NULL" + " AND ip.idPedido=p.id" + " AND ip.fechaEstimada < :arg3" + " AND (p.idTipoEstado=:arg0 OR p.idTipoEstado=:arg1 OR p.idTipoEstado=:arg2)"); qry.setParameter("arg0", Tipo.ESTADO_BOUCHER_ESPERA_PAGO); qry.setParameter("arg1", Tipo.ESTADO_BOUCHER_EN_SERVICIO); qry.setParameter("arg2", Tipo.ESTADO_BOUCHER_RECIBIDO); qry.setParameter("arg3", new Date()); return qry.getResultList(); }
Наконец-то вся его работа. Надеюсь, это вам поможет.
источник
Чтобы добавить к другим ответам: если вам нужна
0000-00-00
строка, вы можете использоватьnoDatetimeStringSync=true
(с предостережением в отношении преобразования часового пояса).Официальная ошибка MySQL: https://bugs.mysql.com/bug.php?id=47108 .
Кроме того, для истории JDBC возвращался
NULL
для0000-00-00
дат, но теперь по умолчанию возвращает исключение. Источникисточник
вы можете добавить URL-адрес jdbc с помощью
?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
С помощью этого sql конвертирует '0000-00-00 00:00:00' как нулевое значение.
например:
jdbc:mysql:<host-name>/<db-name>?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
источник