Usando setDate en PreparedStatement
Para hacer que nuestro código sea más estándar, se nos pidió que cambiáramos todos los lugares donde codificamos nuestras variables SQL a declaraciones preparadas y que vinculáramos las variables en su lugar.
Sin embargo, estoy enfrentando un problema con elsetDate()
.
Aquí está el código:
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));
Recibo este error cuando se ejecuta el SQL:
java.lang.IllegalArgumentException
at java.sql.Date.valueOf(Date.java:138)
at com.cmsi.eValuate.TAF.TAFModuleMain.CallTAF(TAFModuleMain.java:1211)
¿Debería usarlo setString()
en su lugar con a to_date()
?
❐ Usandojava.sql.Date
Si su tabla tiene una columna de tipo DATE
:
java.lang.String
El método
java.sql.Date.valueOf(java.lang.String)
recibió una cadena que representa una fecha en el formatoyyyy-[m]m-[d]d
. p.ej:ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
java.util.Date
Supongamos que tienes una variable
endDate
de tipojava.util.Date
, realizas la conversión así:ps.setDate(2, new java.sql.Date(endDate.getTime());
Actual
Si desea insertar la fecha actual:
ps.setDate(2, new java.sql.Date(System.currentTimeMillis())); // Since Java 8 ps.setDate(2, java.sql.Date.valueOf(java.time.LocalDate.now()));
❐ Usandojava.sql.Timestamp
Si su tabla tiene una columna de tipo TIMESTAMP
o DATETIME
:
java.lang.String
El método
java.sql.Timestamp.valueOf(java.lang.String)
recibió una cadena que representa una fecha en el formatoyyyy-[m]m-[d]d hh:mm:ss[.f...]
. p.ej:ps.setTimestamp(2, java.sql.Timestamp.valueOf("2013-09-04 13:30:00");
java.util.Date
Supongamos que tienes una variable
endDate
de tipojava.util.Date
, realizas la conversión así:ps.setTimestamp(2, new java.sql.Timestamp(endDate.getTime()));
Actual
Si necesita la marca de tiempo actual:
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
Con JDBC 4.2 o posterior y java 8 o posterior:
myPreparedStatement.setObject( … , myLocalDate )
…y…
myResultSet.getObject( … , LocalDate.class )
Detalles
La respuesta de Vargas es buena al mencionar los tipos java.time, pero se refiere solo a la conversión a java.sql.Date. No es necesario realizar la conversión si su controlador está actualizado.
java.tiempo
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases reemplazan a las antiguas y problemáticas clases de fecha y hora como java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
. El equipo de Joda-Time también recomienda la migración a java.time.
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones.
Gran parte de la funcionalidad java.time está adaptada a Java 6 y 7 en ThreeTen-Backport y se adapta aún más a Android en ThreeTenABP .
LocalDate
En java.time, la java.time.LocalDate
clase representa un valor de solo fecha sin hora del día y sin zona horaria.
Si utiliza un controlador JDBC compatible con la especificación JDBC 4.2 o posterior, no es necesario utilizar la java.sql.Date
clase anterior. Puede pasar/obtener LocalDate
objetos directamente desde/hacia su base de datos a través de PreparedStatement::setObject
y ResultSet::getObject
.
LocalDate localDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );
myPreparedStatement.setObject( 1 , localDate );
…y…
LocalDate localDate = myResultSet.getObject( 1 , LocalDate.class );
Antes de JDBC 4.2, convierta
Si su controlador no puede manejar los tipos java.time directamente, recurra a la conversión a tipos java.sql. Pero minimice su uso, y su lógica empresarial utilice únicamente tipos java.time.
Se han agregado nuevos métodos a las clases antiguas para la conversión hacia/desde tipos java.time. Para java.sql.Date
ver los métodos valueOf
y toLocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
…y…
LocalDate localDate = sqlDate.toLocalDate();
Valor del marcador de posición
Tenga cuidado al utilizar 0000-00-00
como valor de marcador de posición el que se muestra en el código de su pregunta. No todas las bases de datos y otros programas pueden soportar retroceder tanto en el tiempo. Sugiero usar algo como la fecha de referencia de la época Unix/Posix de uso común de 1970 1970-01-01
.
LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting.
Acerca de java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases reemplazan a las antiguas y problemáticas clases de fecha y hora heredadas , como java.util.Date
, Calendar
y SimpleDateFormat
.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posteriores
- Incorporado.
- Parte de la API de Java estándar con una implementación incluida.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad java.time está adaptada a Java 6 y 7 en ThreeTen-Backport .
- Androide
- Versiones posteriores de implementaciones de paquetes de Android de las clases java.time.
- Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP… .
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como , Interval
, y más .YearWeek
YearQuarter