Utilisation de setDate dans la préparation
afin de rendre notre code plus standard, nous avons été invités à changer tous les endroits où nous avons hardcoded nos variables SQL à des déclarations préparées et à lier les variables à la place.
je suis cependant confronté à un problème avec le setDate()
.
voici le code:
DateFormat dateFormatYMD = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
DateFormat dateFormatMDY = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date now = new Date();
String vDateYMD = dateFormatYMD.format(now);
String vDateMDY = dateFormatMDY.format(now);
String vDateMDYSQL = vDateMDY ;
java.sql.Date date = new java.sql.Date(0000-00-00);
requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (REQUEST_ID," +
" ORDER_DT, FOLLOWUP_DT) " + "values(?,?,?,)";
prs = conn.prepareStatement(requestSQL);
prs.setInt(1,new Integer(requestID));
prs.setDate(2,date.valueOf(vDateMDYSQL));
prs.setDate(3,date.valueOf(sqlFollowupDT));
j'obtiens cette erreur quand le SQL est exécuté:
java.lang.IllegalArgumentException
at java.sql.Date.valueOf(Date.java:138)
at com.cmsi.eValuate.TAF.TAFModuleMain.CallTAF(TAFModuleMain.java:1211)
si j'utilise setString()
à la place de to_date()
?
6 réponses
utilisation de java.sql.Date
si votre table a une colonne de type DATE
:
-
java.lang.String
La méthode
java.sql.Date.valueOf(java.lang.String)
a reçu une chaîne de caractères représentant une date au formatyyyy-[m]m-[d]d
. par exemple:ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
-
java.util.Date
supposons que vous ayez une variable
endDate
de typejava.util.Date
, vous faites la conversion ainsi:ps.setDate(2, new java.sql.Date(endDate.getTime());
-
Actuel
si vous voulez insérer la date actuelle:
ps.setDate(2, new java.sql.Date(System.currentTimeMillis())); // Since Java 8 ps.setDate(2, java.sql.Date.valueOf(java.time.LocalDate.now()));
utilisation de java.sql.Timestamp
si votre table a une colonne de type TIMESTAMP
ou DATETIME
:
-
java.lang.String
La méthode
java.sql.Timestamp.valueOf(java.lang.String)
a reçu une chaîne de caractères représentant une date au formatyyyy-[m]m-[d]d hh:mm:ss[.f...]
. par exemple:ps.setTimestamp(2, java.sql.Timestamp.valueOf("2013-09-04 13:30:00");
-
java.util.Date
supposons que vous ayez une variable
endDate
de typejava.util.Date
, vous faites la conversion ainsi:ps.setTimestamp(2, new java.sql.Timestamp(endDate.getTime()));
-
Actuel
si vous avez besoin de l'horodatage actuel:
ps.setTimestamp(2, new java.sql.Timestamp(System.currentTimeMillis())); // Since Java 8 ps.setTimestamp(2, java.sql.Timestamp.from(java.time.Instant.now())); ps.setTimestamp(2, java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()));
tl; dr
avec JDBC 4.2 ou plus tard et java 8 ou plus tard:
myPreparedStatement.setObject( … , myLocalDate )
... et ...
myResultSet.getObject( … , LocalDate.class )
détails
la réponse de Vargas est bonne à propos de java.les types de temps mais se réfère uniquement à la conversion en java.SQL.Date. Pas besoin de convertir si votre pilote est mis à jour.
de java.temps
Le de java.time framework est intégré à Java 8 et plus tard. Ces classes supplantent les anciennes classes de date ennuyeuses telles que java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
. L'équipe Joda-Time conseille également la migration vers java.temps.
pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications.
une grande partie de la java.la fonctionnalité time est rétroportée à Java 6 & 7 en ThreeTen-Backport et adapté pour Android dans ThreeTenABP .
LocalDate
en java.heure, la classe java.time.LocalDate
représente une date sans Heure de la journée et sans fuseau horaire.
si vous utilisez un conducteur JDBC conforme à JDBC 4.2 ou une spécification ultérieure, il n'est pas nécessaire d'utiliser le vieux java.sql.Date
de la classe. Vous pouvez passer / récupérer des objets LocalDate
directement à / depuis votre base de données via PreparedStatement::setObject
et ResultSet::getObject
.
LocalDate localDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );
myPreparedStatement.setObject( 1 , localDate );
... et ...
LocalDate localDate = myResultSet.getObject( 1 , LocalDate.class );
avant JDBC 4.2, convertir
si votre pilote ne peut pas gérer le java.les types de temps directement, retombent à la conversion en java.les types sql. Mais minimisent leur utilisation, avec votre logique d'entreprise en utilisant seulement java.les types d'heures.
de nouvelles méthodes ont été ajoutées aux anciennes classes pour la conversion en/à partir de java.les types d'heures. Pour java.sql.Date
voir les méthodes valueOf
et toLocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
... et ...
LocalDate localDate = sqlDate.toLocalDate();
valeur de l'espace Réservé
méfiez - vous de l'utilisation 0000-00-00
comme une valeur de placeholder comme indiqué dans le code de votre Question. Toutes les bases de données et tous les autres logiciels ne peuvent pas remonter aussi loin dans le temps. Je suggère d'utiliser quelque chose comme la date de référence Unix/Posix epoch de 1970, 1970-01-01
.
LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting.
à Propos de de java.heure
Le de java.temps cadre est intégré dans Java 8 et plus tard. Ces classes remplacent les anciennes classes de date legacy telles que java.util.Date
, Calendar
, & SimpleDateFormat
.
le Joda-Time projet, maintenant en mode maintenance , conseille la migration vers le java.time classe.
pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .
vous pouvez échanger java.temps objets directement avec votre base de données. Utiliser un JDBC driver conforme à JDBC 4.2 ou plus tard. Pas besoin de les chaînes, pas besoin de java.sql.*
des classes.
où obtenir le java.les classes de temps?
- Java SE 8 , Java SE 9 , Java SE 10 , et plus tard
- Built-in.
- fait partie de L'API Java standard avec une application.
- Java 9 ajoute des fonctionnalités mineures et des corrections.
- Java SE 6 et Java SE 7
- une grande partie de la java.la fonctionnalité time est rétroportée à Java 6 & 7 dans ThreeTen-Backport .
- Android
- versions ultérieures des implémentations du pack Android de java.les classes de temps.
- Pour plus tôt Android (<26 ans), le ThreeTenABP "1519420920 projet" s'adapte ThreeTen-Backport (mentionné ci-dessus). Voir comment utiliser ThreeTenABP... .
Le ThreeTen-Extra le projet s'étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver des classes utiles ici telles que Interval
, YearWeek
, YearQuarter
, et plus .
le problème que vous avez est que vous passez des formats incompatibles à partir d'un java formaté.util.Date pour construire une instance de java.sql.Date
, qui ne se comportent pas de la même manière en utilisant valueOf()
puisqu'ils utilisent des formats différents.
je peux aussi voir que vous visez à persister des heures et des minutes, et je pense que vous feriez mieux de changer le type de données à java.sql.Timestamp
, qui prend en charge des heures et des minutes, ainsi que de changer votre champ de base de données en DATETIME ou similaire (selon votre fournisseur de base de données).
de toute façon, si vous voulez changer de java.util.Date to java.sql.Date
, je vous suggère d'utiliser
java.util.Date date = Calendar.getInstance().getTime();
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
// ... more code here
prs.setDate(sqlDate);
le docs dit explicitement que java.sql.Date
lancera:
IllegalArgumentException
- si la date indiquée n'est pas dans le format JDBC date escape (yyyy-[m]m-[d]d
)
aussi vous ne devriez pas avoir besoin de convertir une date à un String
puis à un sql.date
, cela semble superflu (et bug-prone!). Au lieu de cela, vous pourriez:
java.sql.Date sqlDate := new java.sql.Date(now.getTime());
prs.setDate(2, sqlDate);
prs.setDate(3, sqlDate);
si vous voulez ajouter la date courante dans la base de données, j'éviterais de calculer la date en Java pour commencer. Déterminer "maintenant" du côté Java (client) mène à des incohérences possibles dans la base de données si le côté client est mal configuré, a le mauvais moment, le mauvais fuseau horaire, etc. Au lieu de cela, la date peut être définie du côté du serveur d'une manière telle que:
requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (" +
"REQUEST_ID, ORDER_DT, FOLLOWUP_DT) " +
"VALUES(?, SYSDATE, SYSDATE + 30)";
...
prs.setInt(1, new Integer(requestID));
ainsi, un seul paramètre bind est requis et les dates sont calculé sur le côté serveur. Encore mieux serait d'ajouter un insert trigger à CREDIT_REQ_TITLE_ORDER
et avoir le trigger insert dates. Cela peut aider à renforcer la cohérence entre les différentes applications client (par exemple, quelqu'un qui essaie de faire une correction via sqlplus.
Pas sûr, mais je pense que vous cherchez est de créer un java.util.Dater à partir d'une chaîne, puis convertir ce java.util.Date en java.SQL.Date.
essayez ceci:
private static java.sql.Date getCurrentDate(String date) {
java.util.Date today;
java.sql.Date rv = null;
try {
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
today = format.parse(date);
rv = new java.sql.Date(today.getTime());
System.out.println(rv.getTime());
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
return rv;
}
}
renvoie un java.SQL.Objet Date pour setDate();
la fonction ci-dessus affichera une valeur longue:
1375934400000