obsługa wartości DATETIME 0000-00-00 00: 00: 00 w JDBC
Dostaję wyjątek (patrz poniżej), jeśli próbuję zrobić
resultset.getString("add_date");
Dla połączenia JDBC z bazą danych MySQL zawierającą wartość DATETIME 0000-00-00 00: 00: 00 (quasi-null wartość dla DATETIME), mimo że próbuję uzyskać wartość jako string, a nie jako obiekt.
Obejrzałem to robiąc
SELECT CAST(add_date AS CHAR) as add_date
Co działa, ale wydaje się głupie... jest na to lepszy sposób?
Chodzi mi o to, że chcę tylko surowy łańcuch DATETIME, więc mogę sam go przeanalizować Jak jest .
Uwaga: Oto gdzie wchodzi 0000: (z http://dev.mysql.com/doc/refman/5.0/en/datetime.html )
Nielegalne DATETIME, Data lub znacznik czasu wartości są konwertowane na " zero" wartość odpowiedniego typu ('0000-00-00 00: 00: 00' lub '0000-00-00').
Szczególnym wyjątkiem jest ten:
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)
10 answers
Natknąłem się na to, próbując rozwiązać ten sam problem. Instalacja, z którą pracuję wykorzystuje JBOSS i Hibernate, więc musiałem to zrobić w inny sposób. Dla podstawowego przypadku, powinieneś być w stanie dodać zeroDateTimeBehavior=convertToNull
do Uri połączenia, jak na tej stronie Właściwości konfiguracji .
Znalazłem inne sugestie dotyczące umieszczenia tego parametru w konfiguracji hibernate:
In hibernate.cfg.xml :
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
In hibernate.właściwości :
hibernate.connection.zeroDateTimeBehavior=convertToNull
Ale musiałem umieścić go w moim mysql-ds.plik xml dla JBOSS jako:
<connection-property name="zeroDateTimeBehavior">convertToNull</connection-property>
Mam nadzieję, że to komuś pomoże. :)Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 13:24:00
Alternatywna odpowiedź, możesz użyć tego adresu URL JDBC bezpośrednio w konfiguracji źródła danych:
jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull
Edit:
Source: MySQL Manual
Datetimes with all-zero components (0000-00-00 ...)- Wartości te nie mogą być rzetelnie reprezentowane w Javie. Złącze / J 3.0.x zawsze konwertuje je na NULL podczas odczytu z ResultSet.
Connector / J 3.1 domyślnie wyświetla wyjątek, gdy te wartości są napotkane, ponieważ jest to najbardziej poprawne zachowanie zgodne ze standardami JDBC i SQL. To zachowanie można zmienić za pomocą właściwości konfiguracyjnej zerodatetimebehavior. Dopuszczalne wartości to:
- wyjątek (domyślnie), który wyrzuca SQLException z SQLState s1009.
- convertToNull , który zwraca NULL zamiast daty.
- Runda , która zaokrągla datę do najbliższej najbliższej wartości, która wynosi 0001-01-01.
Aktualizacja: Alexander zgłosił błąd wpływający na mysql-connector-5.1.15 na tej funkcji. Zobacz CHANGELOGI na oficjalnej stronie internetowej .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 14:01:51
Chodzi mi o to, że chcę tylko surowy łańcuch DATETIME, więc mogę go przeanalizować tak, jak jest.
To sprawia, że myślę, że Twoje "obejście" nie jest obejściem, ale w rzeczywistości jedynym sposobem, aby uzyskać wartość z bazy danych do kodu:
SELECT CAST(add_date AS CHAR) as add_date
Przy okazji, kilka uwag z Dokumentacji MySQL:
MySQL ograniczenia niepoprawnych danych :
Przed MySQL 5.0.2, MySQL wybacza nielegalne lub niewłaściwe wartości danych i przymusza je do wartości prawnych dla wprowadzania danych. W MySQL 5.0.2 i nowszych, które pozostaje domyślnym zachowaniem, ale można zmienić tryb SQL serwera, aby wybrać bardziej tradycyjne traktowanie złych wartości, tak że serwer odrzuca je i przerywa instrukcję, w której występują.
[..]
Jeśli spróbujesz zapisać NULL do kolumny, która nie przyjmuje wartości NULL, wystąpi błąd dla instrukcji INSERT z jednym wierszem. Dla instrukcji INSERT wielowierszowych lub dla INSERT INTO ... Select statements, Serwer MySQL przechowuje domyślną wartość dla typu danych kolumny.
MySQL 5.x typy daty i czasu :
MySQL pozwala również na przechowywanie '0000-00-00' jako "dummy date" (jeśli nie używasz trybu NO_ZERO_DATE SQL). Jest to w niektórych przypadkach wygodniejsze (i zużywa mniej przestrzeni danych i indeksów) niż używanie wartości NULL.
[..]
Domyślnie, gdy MySQL napotka wartość dla Typu daty lub czasu, który jest poza zakresem lub w inny sposób nielegalne dla typu (jak opisano na początku tej sekcji), zamienia wartość na wartość "zero" dla tego typu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-23 20:21:40
DATE_FORMAT(column name, '%Y-%m-%d %T') as dtime
Użyj tego, aby uniknąć błędu. Zwraca datę w formacie string, a następnie można ją uzyskać jako ciąg znaków.
resultset.getString("dtime");
To nie działa. Nawet jeśli nazywasz getString. Wewnętrznie mysql nadal próbuje przekonwertować go do daty jako pierwszy.
[[2]}w Kom.mysql.jdbc.WynikigetDateFromString (ResultSetImpl.java:2270)~ [mysql-connector-java-5.1.15.jar: na] w Kom.mysql.jdbc.WynikigetStringInternal (ResultSetImpl.Java:5743)
~ [mysql-connector-java-5.1.15.jar: na] w Kom.mysql.jdbc.WynikigetString (ResultSetImpl.Java:5576)
~ [mysql-connector-java-5.1.15.jar: na]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 22:33:40
If, po dodaniu linii:
<property
name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
hibernate.connection.zeroDateTimeBehavior=convertToNull
<connection-property
name="zeroDateTimeBehavior">convertToNull</connection-property>
Nadal jest błędem:
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').
Znajdź linie:
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
Zastąpić odpowiednio następującymi wierszami:
1) Time.valueOf(resultSet.getString("time"));
2) Timestamp.valueOf(resultSet.getString("timestamp"));
3) Date.valueOf(resultSet.getString("date"));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-09 15:19:21
Zmagałem się z tym problemem i zaimplementowałem omówione powyżej rozwiązania "convertToNull". To działało w mojej lokalnej instancji MySql. Ale kiedy wdrożyłem moją aplikację Play / Scala do Heroku, nie będzie już działać. Heroku łączy również kilka args do adresu URL DB, który dostarczają użytkownikom, A To rozwiązanie, ze względu na użycie Heroku konkatenacja"?"przed własnym zestawem args, nie będzie działać. Znalazłem jednak inne rozwiązanie, które wydaje się działać równie dobrze.
SET SQL_MODE = "NO_ZERO_DATE";
Umieściłem to w opisach tabeli i rozwiązało to problem '0000-00-00 00: 00: 00' nie może być reprezentowany jako java.sql.Timestamp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 23:37:52
Sugeruję użycie null do reprezentowania wartości null.
Jaki masz wyjątek?
BTW:
Nie ma roku o nazwie 0 lub 0000. (Choć niektóre daty pozwalają w tym roku)
I nie ma 0 miesiąca roku ani 0 dnia miesiąca. (Co może być przyczyną twojego problemu)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-23 19:43:35
Rozwiązałem problem rozważając '00-00-....'isn' is a valid date, then, I changed my SQL column definition adding" NULL " expresion to permit null values:
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),...
Następnie muszę być w stanie wstawić wartości NULL, co oznacza "nie zarejestrowałem jeszcze tego znacznika czasu"...
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),...
Tabela wygląda tak:
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)
Wreszcie: JPA w akcji:
@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();
}
W końcu cała jego praca. Mam nadzieję, że ci to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-19 18:17:39
Aby dodać do pozostałych odpowiedzi: jeśli chcesz 0000-00-00
, możesz użyć noDatetimeStringSync=true
(z zastrzeżeniem poświęcenia konwersji strefy czasowej).
Oficjalny błąd MySQL: https://bugs.mysql.com/bug.php?id=47108 .
Również w przypadku historii, JDBC zwracało NULL
dla 0000-00-00
dat, ale teraz domyślnie zwraca wyjątek.
Źródło
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-29 02:13:48
Możesz dołączyć adres URL jdbc za pomocą
?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
Z pomocą tego, SQL konwertuje '0000-00-00 00:00:00' jako wartość null.
Eg:
jdbc:mysql:<host-name>/<db-name>?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-23 08:12:05