java.sql.SQLDataException: ORA-01858: не числовой символ был найден там, где ожидалось число при дате обновления - PullRequest
0 голосов
/ 08 ноября 2018

Ниже мое заявление sql в Java DAO. Когда я пытаюсь обновить дату заезда и проверки, я получаю сообщение об ошибке:

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 голосов
/ 08 ноября 2018

tl; dr

Никогда не используйте старые ужасные устаревшие классы даты и времени, такие как java.sql.Date, java.util.Date, Calendar и `SimpleDateFormat.Используйте их замену, современные java.time классы.

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

… и…

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

java.time

Ответ Крума является правильным, за исключением того, что он использует ужасный класс 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.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10, Java SE 11 и более поздних версий - часть стандартного API Java с связанной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесено в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Вы можете найти здесь несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 08 ноября 2018

Это происходит потому, что вы пытаетесь передать строки в оператор update, но ожидают типы даты в полях checkin и checkout.

Для вашего 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. Для первого варианта просто передайте атрибут даты в stmt.setDate

Также Здесь - пример того, как правильно написать команду update.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...