Конвертировать строку в TIMESTAMP для вставки в базу данных оракула из сервлета Java - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь вставить дату в поле TIMESTAMP в базе данных Oracle из сервлета.но когда я делаю вставку, я получаю сообщение об ошибке: «ORA-01843: месяц недействителен»

Тип даты, которую я вижу в таблице, где это дата: 05-FEB-19 09.36.10.0000000 утра, и я объявил это, когда таблица была создана как тип TIMESTAMP.

В файле JSP у меня есть этот 2 типа ввода:

<label>Data
<input type="date" name="date" value="13-AUG-2019" required>
</label>
<label>Time
<input type="time" name="time" value="11:00:00 AM" required>
</label>

В сервлете Java у меня есть это:

    String data= request.getParameter("date");
    String time= request.getParameter("time");
    String paramData = data.replaceAll("\n", "");
    String paramTime = time.replaceAll("\n", "");
    String dataTime = paramData + " " + paramTime;

    try{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection connCf = DriverManager.getConnection(url, user, pass);

        PreparedStatement pstmtCf=connCf.prepareStatement("insert into screening_tab (film_oid, room_oid, data_hour) values((select ref(fi) from film_tab fi where fi.title=?), (select ref(ro) from room_tab ro where ro.code=?), ?)");

        pstmtCf.setString(1, paramFilm);
        pstmtCf.setString(2, paramRoom);
        String paramDataTime= paramData + " " + paramTime;
        pstmtCf.setString(3, paramDataTime);

        Boolean result= pstmtCf.execute();

как я могу решить эту проблему?

Я пробовал это решение в Oracle 10, которое дает строку из сервлета, возвращает метку времени, но проблема та же:

create or replace procedure Sdata (datatime VarCHAR2) is
date_ho TIMESTAMP;
begin
SELECT TO_TIMESTAMP (datatime, 'DD-MON-RR HH.MI.SSXFF AM') into date_ho  FROM DUAL;
dbms_output.enable;
dbms_output.put_line(date_ho);
end sdata;

Между различными попытками и испытаниями я не могу объяснить, как, если я делаю что-то подобное в Oracle SQL Developer, все работает правильно!:

insert into screening_tab (film_oid, room_oid, data_hour) values((select ref(fi) from film_tab fi where fi.title='FilmNumero601'), (select ref(ro) from room_tab ro where ro.code=301), '14-DEC-19 07.00.00.00 PM' );

, когда я запускаю точно такой же запрос из сервлетаЯ всегда получаю сообщение об ошибке с недопустимой датой месяца

. Я пробовал также это решение: я создал новый файл сервлета и JSP, в котором этот вход для данных:

<h4>Select Data: </h4><br></br>
                                <input type="datetime-local"  name="date" arequired placeholder="Date">
                                <br></br>
                                <input type="reset"  value="Resetta la form"></input>
                                <input type="submit" value="Invia"></input>

Всоответствующий сервлет у меня есть это:

PreparedStatement pstmtCf=connCf.prepareStatement("insert into screening_tab (film_oid, room_oid, data_hour) values((select ref(fi) from film_tab fi where fi.title=?), (select ref(ro) from room_tab ro where ro.code=?), ?)");



            pstmtCf.setString(1, film);
            pstmtCf.setString(2, room);
            String date= getCorrectFormat(request.getParameter("date")+":00");
            pstmtCf.setString(3, date );


            pstmtCf.execute();



            pstmtCf.close();
            connCf.close();

Где getCorrectFormat ():

public static String getCorrectFormat(String date){
        String out="";
        out += (date.substring(8,10))+ "-";
        switch(date.substring(5,7)){
        case "01":
            out += "JAN-";
            break;
        case "02":
            out += "FEB-";
            break;
        case "03":
            out += "MAR-";
            break;
        case "04":
            out += "APR-";
            break;
        case "05":
            out += "MAY-";
            break;
        case "06":
            out += "JUN-";
            break;
        case "07":
            out += "JUL-";
            break;
        case "08":
            out += "AUG-";
            break;  
        case "09":
            out += "SEP-";
            break;
        case "10":
            out += "OCT-";
            break;
        case "11":
            out += "NOV-";
            break;
        case "12":
            out += "DEC-";
            break;
        }
        out += (date.substring(0,4))+ " ";
        int hour =Integer.parseInt(date.substring(11,13))%12;
        if(hour == 0)
            out += String.valueOf(12);
        else
            out += String.valueOf(hour);
        out += (date.substring(13));
        if(Integer.parseInt(date.substring(11,13))<12)
            out += " AM";
        else
            out += " PM";
        return out;
    }

Ошибка всегда одинакова: «ORA-01843: недопустимый месяц»

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Используйте объекты, а не строки.

Начиная с JDBC 4.2, мы можем напрямую обмениваться java.time объектами с базой данных с помощью методов PreparedStatement::setObject & ResultSet::getObject.В подготовленном заявлении используйте ? заполнителей, как показано в Oracle Tutorial .

LocalDate ld = LocalDate.of( 2019 , 8 , 13 ) ;
myPreparedStatement.setObject( … , ld ) ;

И…

LocalTime lt = LocalTime.of( 11 , 0 ) ;
myPreparedStatement.setObject( … , lt ) ;

Извлечение.

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
LocalDate lt = myResultSet.getObject( … , LocalTime.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 и более поздние версии - часть стандартного Java API с связанной реализацией.
    • 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 февраля 2019

Вы передаете String / varchar2, и неявное преобразование в метку времени не выполняется, поскольку ваш формат даты / времени не соответствует формату даты и времени Oracle по умолчанию.

Самый простой вариант - передать строку формата, чтобы Oracle знал, как выполнить преобразование.Вместо того, чтобы передавать ? для отметки времени, вы можете сделать to_timestamp(?, 'DD-MON-YYYY HH:MI:SS AM')

Если у вас уже была отметка времени Java, я думаю, что вы захотите использовать setTimestamp() - , посмотрите этот вопрос .

...