在PreparedStatement中使用setDate

roy*_*g86 45 java sql oracle jdbc prepared-statement

为了使我们的代码更加标准化,我们被要求将我们将SQL变量硬编码的所有位置更改为预处理语句并改为绑定变量.

然而,我面临着一个问题setDate().

这是代码:

        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));
Run Code Online (Sandbox Code Playgroud)

SQL执行时出现此错误:

    java.lang.IllegalArgumentException
    at java.sql.Date.valueOf(Date.java:138)
    at com.cmsi.eValuate.TAF.TAFModuleMain.CallTAF(TAFModuleMain.java:1211)
Run Code Online (Sandbox Code Playgroud)

我应该使用setString(),而不是用to_date()

Pau*_*gas 133

❐使用 java.sql.Date

如果您的表有一列类型DATE:

❐使用 java.sql.Timestamp

如果您的表有一个类型列TIMESTAMPDATETIME:


Bas*_*que 17

TL;博士

使用JDBC 4.2或更高版本以及Java 8或更高版本:

myPreparedStatement.setObject( … , myLocalDate  )
Run Code Online (Sandbox Code Playgroud)

…和…

myResultSet.getObject( … , LocalDate.class )
Run Code Online (Sandbox Code Playgroud)

细节

Vargas的回答很好地提到了java.time类型,但仅指转换为java.sql.Date.如果您的驱动程序已更新,则无需转换.

java.time

java.time框架是建立在Java 8和更高版本.这些类取代旧的麻烦日期时间类,如java.util.Date,.Calendar,和java.text.SimpleDateFormat.该乔达时球队还建议迁移java.time.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.

大部分java.time功能都在ThreeTen- Backport中反向移植到Java 6和7,并进一步适用于ThreeTenABP中的 Android .

LocalDate

在java.time中,java.time.LocalDate该类表示没有时间且没有时区的仅日期值.

如果使用符合JDBC 4.2或更高版本规范的JDBC驱动程序,则无需使用旧类.您可以通过/取通过直接从您的数据库对象/ 和.java.sql.DateLocalDatePreparedStatement::setObjectResultSet::getObject

LocalDate localDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );
myPreparedStatement.setObject( 1 , localDate  );
Run Code Online (Sandbox Code Playgroud)

…和…

LocalDate localDate = myResultSet.getObject( 1 , LocalDate.class );
Run Code Online (Sandbox Code Playgroud)

在JDBC 4.2之前,转换

如果您的驱动程序无法直接处理java.time类型,请回退到转换为java.sql类型.但是最小化它们的使用,使用仅使用java.time类型的业务逻辑.

旧类中添加了新方法,用于转换为/从java.time类型转换.对于java.sql.Date看到valueOftoLocalDate方法.

java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
Run Code Online (Sandbox Code Playgroud)

…和…

LocalDate localDate = sqlDate.toLocalDate();
Run Code Online (Sandbox Code Playgroud)

占位符值

警惕使用0000-00-00问题代码中显示的占位符值.并非所有数据库和其他软件都能及时处理.我建议使用像1970年常用的Unix/Posix epoch参考日期1970-01-01.

LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting.
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.