簡體   English   中英

java.sql.SQLDataException:ORA-01858:在更新日期時在非數字字符的位置應找到數字

[英]java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected when update date

以下是我在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;
    }
   }    

   }

發生這種情況是因為您試圖將字符串傳遞給您的update語句,但是它期望在checkincheckout字段上使用Date類型。

對於update語句,應嘗試使用PreparedStatement傳入參數。 閱讀和維護起來要容易得多。 是一個帶有一些有用示例的網站。

現在,對於您的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

另外, 是如何正確編寫update命令的示例。

TL;博士

永遠不要使用可怕的舊舊式日期時間類,例如java.sql.Datejava.util.DateCalendar和`SimpleDateFormat。 使用它們的替代品,即現代的java.time類。

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

…和…

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

java.time

KrumAnswer是正確的,除了它使用了可怕的java.sql.Date類,該類在幾年前因采用JSR 310而過時。 如該答案中所建議,您應該使用智能對象而不是啞字符串來與數據庫交換日期時間值。

讓我們調整一下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及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310

您可以直接與數據庫交換java.time對象。 使用與JDBC 4.2或更高版本兼容的JDBC驅動程序 不需要字符串,不需要java.sql.*類。

在哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM