J'obtiens une exception (voir ci-dessous) si j'essaye de faire
resultset.getString("add_date");
pour une connexion JDBC à une base de données MySQL contenant une valeur DATETIME de 0000-00-00 00:00:00 (la valeur quasi-nulle pour DATETIME), même si j'essaie juste d'obtenir la valeur sous forme de chaîne, pas sous forme de objet.
J'ai contourné ça en faisant
SELECT CAST(add_date AS CHAR) as add_date
qui fonctionne, mais semble idiot ... y a-t-il une meilleure façon de faire cela?
Mon point est que je veux juste la chaîne DATETIME brute, donc je peux l'analyser moi-même tel quel .
note: voici où le 0000 entre en jeu: (à partir de http://dev.mysql.com/doc/refman/5.0/en/datetime.html )
Les valeurs DATETIME, DATE ou TIMESTAMP illégales sont converties en la valeur «zéro» du type approprié («0000-00-00 00:00:00» ou «0000-00-00»).
L'exception spécifique est celle-ci:
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)
Réponse alternative, vous pouvez utiliser cette URL JDBC directement dans la configuration de votre source de données:
jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull
Éditer:
Source: Manuel MySQL
Mise à jour: Alexander a signalé un bogue affectant mysql-connector-5.1.15 sur cette fonctionnalité. Voir CHANGELOGS sur le site officiel .
la source
Cela me fait penser que votre "solution de contournement" n'est pas une solution de contournement, mais en fait le seul moyen d'obtenir la valeur de la base de données dans votre code:
SELECT CAST(add_date AS CHAR) as add_date
Au fait, quelques notes supplémentaires de la documentation MySQL:
Contraintes MySQL sur les données non valides :
Types de date et d'heure MySQL 5.x :
la source
DATE_FORMAT(column name, '%Y-%m-%d %T') as dtime
Utilisez ceci pour éviter l'erreur. Il renvoie la date au format chaîne et vous pouvez ensuite l'obtenir sous forme de chaîne.
resultset.getString("dtime");
Cela ne fonctionne PAS réellement. Même si vous appelez getString. En interne, mysql essaie toujours de le convertir en date en premier.
la source
Si, après avoir ajouté des lignes:
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property> hibernate.connection.zeroDateTimeBehavior=convertToNull <connection-property name="zeroDateTimeBehavior">convertToNull</connection-property>
continue d'être une erreur:
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').
rechercher des lignes:
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
remplacer par les lignes suivantes, respectivement:
1) Time.valueOf(resultSet.getString("time")); 2) Timestamp.valueOf(resultSet.getString("timestamp")); 3) Date.valueOf(resultSet.getString("date"));
la source
J'ai lutté avec ce problème et mis en œuvre les solutions «convertToNull» décrites ci-dessus. Cela a fonctionné dans mon instance MySql locale. Mais lorsque j'ai déployé mon application Play / Scala sur Heroku, cela ne fonctionnait plus. Heroku concatène également plusieurs arguments à l'URL de base de données qu'ils fournissent aux utilisateurs, et cette solution, en raison de la concaténation d'utilisation de Heroku de "?" avant leur propre ensemble d'arguments, ne fonctionnera pas. Cependant, j'ai trouvé une solution différente qui semble fonctionner aussi bien.
SET sql_mode = 'NO_ZERO_DATE';
J'ai mis cela dans mes descriptions de table et cela a résolu le problème de '0000-00-00 00:00:00' ne peut pas être représenté comme java.sql.
la source
Je vous suggère d'utiliser null pour représenter une valeur nulle.
Quelle est l'exception que vous obtenez?
BTW:
Il n'y a pas d'année appelée 0 ou 0000 (bien que certaines dates le permettent cette année)
Et il n'y a ni 0 mois de l'année ni 0 jour du mois. (Ce qui peut être la cause de votre problème)
la source
J'ai résolu le problème en considérant que '00 -00 -.... 'n'est pas une date valide, puis j'ai changé ma définition de colonne SQL en ajoutant une expression "NULL" pour autoriser les valeurs nulles:
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),...
Ensuite, je dois pouvoir insérer des valeurs NULL, ce qui signifie "Je n'ai pas encore enregistré cet horodatage" ...
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),...
La table ressemble à ça:
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)
Enfin: JPA en action:
@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(); }
Enfin tout son travail. J'espère que cela vous aidera.
la source
Pour ajouter aux autres réponses: Si vous voulez la
0000-00-00
chaîne, vous pouvez utilisernoDatetimeStringSync=true
(avec la mise en garde de sacrifier la conversion de fuseau horaire).Le bogue officiel de MySQL: https://bugs.mysql.com/bug.php?id=47108 .
De plus, pour l'historique, JDBC avait l'habitude de retourner
NULL
pour les0000-00-00
dates mais renvoie maintenant une exception par défaut. La sourcela source
vous pouvez ajouter l'url jdbc avec
?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
Avec l'aide de cela, sql convertit '0000-00-00 00:00:00' en valeur nulle.
par exemple:
jdbc:mysql:<host-name>/<db-name>?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
la source