java.sql.SQLDataException:ORA-01858:在更新日期时在非数字字符的位置应找到数字

时间:2018-11-08 15:48:09

标签: java sql oracle

下面是我在Java DAO中的sql语句。尝试更新签入和签出日期时,出现错误消息

  

java.sql.SQLDataException:ORA-01858:一个非数字字符是   找到了期望的数字。

我是否需要使用simpledateformat将签入和签出从字符串转换为日期?如果是,如何在sql语句中插入。

HTML

 <form>
<input type="date" id="checkin" class="form-control" >
<input type="date" id="checkout" class="form-control" >
</form

SQL

CREATE TABLE "HOMESTAY"."BOOKING" 
  ( "BOOKINGNUM" NUMBER(*,0) NOT NULL ENABLE, 
   "CHECKIN" DATE, 
   "CHECKOUT" DATE, 
   "NUMOFDAYS" NUMBER(*,0), 
   "TOTALCHARGES" FLOAT(10), 
   "BFAST" VARCHAR2(10 BYTE), 
   "CUSTIC" VARCHAR2(12 BYTE), 
   "ACCID" NUMBER, 
    CONSTRAINT "BOOKING_PK" PRIMARY KEY ("BOOKINGNUM")

Java

public void updateBooking(BookingBean bean) {


int bookingnum = bean.getBookingnum();
String checkin = bean.getCheckin();
String checkout = bean.getCheckout();
int numofdays = bean.getNumofdays();
float totalcharges = bean.getTotalcharges();
String bfast = bean.getBfast();
String custic = bean.getCustic();
int accid = bean.getAccid();


try {

    currentCon = ConnectionManager.getConnection();
    ps=currentCon.prepareStatement("UPDATE booking SET (checkin , checkout, 
    numofdays, totalcharges, bfast, custic,accid)values(?,?,?,?,?,?,?)");


    String s = checkin;
    Date d = new SimpleDateFormat("yyyy-MM-dd").parse(s);       
    String s1 = checkout;
    Date d1 = new SimpleDateFormat("yyyy-MM-dd").parse(s1);

    ps.setDate(1, new java.sql.Date(d.getTime()));
    ps.setDate(2, new java.sql.Date(d1.getTime()));
    ps.setInt(3,numofdays);
    ps.setFloat(4,totalcharges);
    ps.setString(5, bfast);
    ps.setString(6,custic);
    ps.setInt(7,accid);
    ps.executeUpdate();
   }

    catch (Exception ex) {
    System.out.println("failed: An Exception has occurred! " + ex);
   }

    finally {
    if (ps != null) {
        try {
            ps.close();
        } catch (Exception e) {
        }
        ps = null;
       }

    if (currentCon != null) {
        try {
            currentCon.close();
        } catch (Exception e) {
        }
        currentCon = null;
    }
   }    

   }

2 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您试图将字符串传递给update语句,但是它期望字段checkincheckout上的日期类型。

对于update语句,应尝试使用PreparedStatement传递参数。 Here是一个包含一些有用示例的网站,它更易于阅读和维护。

现在为您的Strings,您可以执行以下两项操作:

第一个是将那些BookingBean属性更改为Date类型。

第二个选择是继续使用您的Strings并将其作为日期传递给PreparedStatement,如下例所示:

try {
    currentCon = ConnectionManager.getConnection();
    PreparedStatement stmt = currentCon.prepareStatement(searchQuery);
    stmt.setDate(1, java.sql.Date.valueOf("2018-11-08"));
    stmt.executeUpdate(searchQuery);

} catch (SQLException e) {
    e.printStackTrace();
}

Ps。对于第一种选择,只需将date属性传递到stmt.setDate

此外,Here是如何正确编写update命令的示例。

答案 1 :(得分:0)

tl; dr

永远不要使用可怕的旧式旧式日期时间类,例如java.sql.Datejava.util.DateCalendar和`SimpleDateFormat。使用它们的替代品,现代的 java.time 类。

myPreparedStatement.setObject( … , LocalDate.parse( "2018-11-08" ) )

…和…

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

java.time

Answer by Krum是正确的,只是它使用了可怕的java.sql.Date类,该类在几年前由于采用JSR 310而过时。正如该“答案”中所建议的那样,您应该使用智能对象而不是哑字符串来与数据库交换日期时间值。

让我们调整code presented by Krum。两项更改:(a)用现代类替换旧类,以及(b)输入错误时分别解析输入字符串。

java.time.LocalDate localDate = null ;             // Use the modern `java.time.LocalDate` class that years ago supplanted the terribly-designed `java.sql.Date` class.
try {
    localDate = LocalDate.parse( "2018-11-08" ) ;  // The java.time classes by default know how to parse strings in standard ISO 8601 format such as seen here.
} catch ( DateTimeParseException e ) {
    … // Deal with invalid input string.
}

try {
    currentCon = ConnectionManager.getConnection() ;
    PreparedStatement stmt = currentCon.prepareStatement( searchQuery ) ;
    stmt.setObject(1, localDate ) ;                // As of JDBC 4.2, we can directly exchange java.time objects with a database via the `setObject` and `getObject` methods.
    stmt.executeUpdate( searchQuery ) ;

} catch (SQLException e) {
    e.printStackTrace() ;
}

并进行检索。

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;

关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore