简体   繁体   English

将String转换为TIMESTAMP,以便从servlet java插入到数据库oracle中

[英]Convert String into TIMESTAMP for insert into Database oracle from servlet java

I'm trying to insert a date into a TIMESTAMP field in an Oracle database from a servlet. 我正在尝试从servlet向Oracle数据库中的TIMESTAMP字段插入日期。 but when I do the insert, I get an error: "ORA-01843: month not valid" 但是当我插入时,我收到一个错误:“ORA-01843:月份无效”

The type of date I see in the table where the date is is this: 05-FEB-19 09.36.10.000000000 AM and I declared it when the table was created as a TIMESTAMP type. 我在表中看到的日期类型是:05-FEB-19 09.36.10.000000000 AM我在表创建为TIMESTAMP类型时声明了它。

In JSP file i have this 2 input type: 在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>

In a Servlet Java i have this: 在Servlet 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();

how can I solve this problem? 我怎么解决这个问题?

I Have tried this solution in Oracle 10 that given a string from servlet returns timestamp but the problem is the same: 我在Oracle 10中尝试过这个解决方案,给出来自servlet的字符串返回时间戳,但问题是相同的:

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;

Between the various attempts and trials, i can not explain how, if I do something like this in Oracle SQL Developer everything works correctly!: 在各种尝试和试验之间,我无法解释如果我在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' );

when I run the exact same query from the servlet I always get the error on the invalid month date 当我从servlet运行完全相同的查询时,我总是在无效的月份日期得到错误

I have tried also this solution: I have created a new Servlet and JSP file where this input for data is: 我也试过这个解决方案:我创建了一个新的Servlet和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>

In the corresponding servlet i have this: 在相应的servlet中我有这个:

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();

Where getCorrectFormat() is: 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;
    }

The error is always the same: "ORA-01843:not a valid month" 错误始终相同:“ORA-01843:无效月份”

Use objects, not strings. 使用对象,而不是字符串。

As of JDBC 4.2, we can directly exchange java.time objects with the database via PreparedStatement::setObject & ResultSet::getObject methods. 从JDBC 4.2开始,我们可以通过PreparedStatement::setObjectResultSet::getObject方法直接与数据库交换java.time对象。 In your prepared statement, use ? 在准备好的声明中,使用? placeholders as seen in Oracle Tutorial . Oracle教程中显示的占位符。

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

And… 和…

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

Retrieval. 恢复。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
LocalDate lt = myResultSet.getObject( … , LocalTime.class ) ;

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用符合JDBC 4.2或更高版本的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

You're passing in a String/varchar2, and the implicit conversion to timestamp is failing because your date/time format doesn't match your Oracle default date/time format. 您传入的是String / varchar2,并且隐式转换为时间戳失败,因为您的日期/时间格式与Oracle默认日期/时间格式不匹配。

The easiest option is to pass a format string so Oracle knows how to do the conversion. 最简单的选择是传递格式字符串,以便Oracle知道如何进行转换。 Instead of passing ? 而不是通过? for the timestamp, you could do to_timestamp(?, 'DD-MON-YYYY HH:MI:SS AM') 对于时间戳,你可以做to_timestamp(?, 'DD-MON-YYYY HH:MI:SS AM')

If you already had a Java Timestamp, I think you'd want to use setTimestamp() - see this question . 如果你已经有了Java时间戳,我想你想使用setTimestamp() - 请看这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM