Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
5.5k views
in Technique[技术] by (71.8m points)

java - Localdatetime parsing exception while reading from oracle resultset column

I am trying to read the property from the oracle resultset into localdatetime, but i am getting DateTimeException because of invalid value of the Month, the value from the resultset is "08-APR-3157 11:46:18".

import java.sql.*;
import java.time.LocalDateTime;

class OracleLocalDateTime{

   public static void main(String a[]){
    try{
        Class.forName(oracle.jdbc.driver.OracleDriver");
        Connection con = DriverManager.getConnection("jdbc:oracle:thin:@ORA60:1555:EMP","scott","tiger");
       Statement stmt = con.createStatement();
       ResultSet rs = stmt.executeQuery("select emp_end_date from employee where emp_id=1234");
       LocalDateTime timestamp = null;
       while(rs.next()){
           timestamp = rs.getObject(1,LocalDateTime.class);
           System.out.println(timestamp);
       }
       con.close();

     }catch(Exception e){

        e.printStackTrace();
     }

   }
}

***Value coming from the oracle is: 08-APR-3157 11:46:18 ***

  java.time.DateTimeException: Invalid value for MonthOfYear(valid values 1 - 12): 112
     at java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
     at java.time.temporal.ChronoField.checkValidValue(ChronoField.java:703)
     at java.time.LocalDate.of(LocalDate.java:267)
     at java.time.LocalDateTime.of(LocalDateTime.java:361)
     at oracle.jdbc.driver.DateTimeCommonAccessor.getLocalDateTime(DateTimeCommonAccessor.java:203)
     at oracle.jdbc.driver.Redirector$31.redirect(Redirector.java:663)
     at oracle.jdbc.driver.Redirector$31.redirect(Redirector.java:658)
     at oracle.jdbc.driver.Representation.getObject(Representation.java:485)
     at oracle.jdbc.driver.Accessor.getObject(Accessor.java:967)
     at oracle.jdbc.driver.InsensitiveScrollableResultSet.getObject(InsensitiveScrollableResultSet.java:592)
     at OracleLocalDateTime.main(OracleLocalDateTime.java:22)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I suspect you have not shown us your actual code, as your SQL is malformed with a double-quote in the middle rather than at the end. You have also not shown important information such as the exact data type of the column in your database.

Complete example storing & retrieving LocalDateTime

With details missing, the best I can do is give you a full example app that inserts and retrieves rows from a database. Here we use H2 Database Engine, though I believe the code would be virtually the same in Oracle. We have a column of type TIMESTAMP WITHOUT TIME ZONE into which we store and retrieve Java objects of type LocalDateTime.

package work.basil.example;

import org.h2.jdbcx.JdbcDataSource;

import java.sql.*;
import java.time.*;
import java.util.UUID;

public class LdtDb
{
    public static void main ( String[] args )
    {
        LdtDb app = new LdtDb();
        app.demo();
    }

    private void demo ( )
    {
        // Establish an object implementing `DataSource` interface.
        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL( "jdbc:h2:mem:localdatetime_example_db;DB_CLOSE_DELAY=-1" ); // Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
        ds.setUser( "scott" );
        ds.setPassword( "tiger" );

        try (
                Connection conn = ds.getConnection() ;
        )
        {
            // Create database.
            String sql = """
                         CREATE TABLE event_ ( 
                             pkey_ UUID NOT NULL DEFAULT RANDOM_UUID() PRIMARY KEY ,
                             when_ TIMESTAMP WITHOUT TIME ZONE NOT NULL 
                         )
                         ;
                         """;
            try (
                    Statement stmt = conn.createStatement() ;
            )
            {
                stmt.execute( sql );
            }

            // Insert row.
            sql = """
                  INSERT INTO event_ ( when_ )
                  VALUES ( ? ) 
                  ;
                  """;
            try (
                    PreparedStatement pstmt = conn.prepareStatement( sql , Statement.RETURN_GENERATED_KEYS ) ;
            )
            {

                // Insert row.
                LocalDateTime localDateTime1 = LocalDateTime.parse( "2021-01-23T11:11:11" );
                pstmt.setObject( 1 , localDateTime1 );
                pstmt.executeUpdate();

                ResultSet rs = pstmt.getGeneratedKeys();
                System.out.println( "INFO - Reporting generated keys." );
                while ( rs.next() )
                {
                    UUID uuid = rs.getObject( 1 , UUID.class );
                    System.out.println( "generated keys: " + uuid );
                }

                // Insert another row.
                LocalDateTime localDateTime2 = LocalDateTime.parse( "2021-02-22T22:22:22" );
                pstmt.setObject( 1 , localDateTime2 );
                pstmt.executeUpdate();
            }


            // Dump all rows.
            System.out.println( "INFO - Reporting all rows in table `event_`." );
            sql = """
                  SELECT * 
                  FROM event_ ;
                  """;
            try (
                    Statement stmt = conn.createStatement() ;
                    ResultSet rs = stmt.executeQuery( sql ) ;
            )
            {
                while ( rs.next() )
                {
                    UUID pkey = rs.getObject( "pkey_" , UUID.class );
                    LocalDateTime localDateTime = rs.getObject( "when_" , LocalDateTime.class );
                    System.out.println( "Event: " + pkey + " | " + localDateTime );
                }
            }
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
    }
}

When run.

INFO - Reporting generated keys.
generated keys: bcad0c3c-f666-4075-8625-b406ffb42baa
INFO - Reporting all rows in table `event_`.
Event: bcad0c3c-f666-4075-8625-b406ffb42baa | 2021-01-23T11:11:11
Event: 4f9eef5b-90ea-4f6a-b4ad-dcd0886ff89a | 2021-02-22T22:22:22

Timestamp suggests a moment; LocalDateTime is not a moment

You named your variable:

LocalDateTime timestamp

The word "timestamp" suggests you mean to represent a moment, a specific point on the timeline. But a LocalDateTime does not represent a moment. That class represents a date with a time-of-day but lacks the context of a time zone or offset-from-UTC. For example, a LocalDateTime parsed from `2021-01-23T12:00:00" means noon on the 23rd. But we do not know if that is noon in Tokyo Japan, noon in Toulouse France, or noon in Toledo Ohio US — three very different moments several hours apart.

If you are tracking a moment, use one of the three java.time classes Instant, OffsetDateTime, or ZonedDateTime with a database column of a type akin to the SQL-standard type TIMESTAMP WITH TIME ZONE.

If you are not tracking moments, such as booking future appointments, then use Java class LocalDateTime with SQL type TIMESTAMP WITHOUT TIME ZONE.

Table of date-time types in Java (both legacy and modern) and in standard SQL


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...