0

i have the the sql schema on sql server i am trying to insert the values in the table but i am getting error when i am trying to insert Year data type in sql I have parsed the string to year data type for example

double c=Double.parseDouble("2019.0");
int yt=(int) c;
Year business_year; 
business_year=Year.parse(String.format("%04d", yt));
String qq="INSERT INTO invoice_details VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(qq);
pstmt.setYear(1,business_year);

pstmt.setYear(1,business_year); in this line i am getting the following error

The method setDate(int, Date) in the type PreparedStatement is not applicable for the arguments (int, Year).

could someone please help in it.

Shhh_8279
  • 41
  • 7
  • does `PreparedStatement` really has a method `setYear` - even error message is telling something else - anyway, the method `setDate` does not accept a `Year`, only a `Date` or subclass of it –  Feb 28 '21 at 16:42
  • @user15244370 No it doesn't how to do that? how to insert Year data type in sql – Shhh_8279 Feb 28 '21 at 16:43
  • what exactly you want to store in Database? What is the column type? –  Feb 28 '21 at 16:44
  • @user15244370 column datatype in sql schema is Year i want to insert into the table – Shhh_8279 Feb 28 '21 at 16:45
  • checking the [documentation](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-type-conversions.html) suggest it must be a `Date` (`setDate`) or short (`setShort`) - maybe even String is accepted (`setString`) –  Feb 28 '21 at 16:46
  • @user15244370 so how to insert in to the table? Year datatype – Shhh_8279 Feb 28 '21 at 16:48
  • see last comment, or try `setObject` (maybe `setDate` with `Date.valueOf(business_year.atDay(1))`) –  Feb 28 '21 at 16:49
  • how do we convert from Year data type to String ? – Shhh_8279 Feb 28 '21 at 17:03
  • @Akina there is Year datatype – Shhh_8279 Feb 28 '21 at 17:57
  • and i am still facing the issue – Shhh_8279 Feb 28 '21 at 17:57
  • @Akina please go through this (https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-type-conversions.html) – Shhh_8279 Feb 28 '21 at 18:09
  • Year to string is `business_year.toString()` (but also try `set Date(1, java.sql.Date.valueOf(business_year.atDay(1)))`, I've no MySql to test here) –  Feb 28 '21 at 18:14
  • @user15244370 its giving error when i am trying to insert the data in the "Date" data type – Shhh_8279 Feb 28 '21 at 20:34

1 Answers1

0

Caveat: I do not use MySQL. I did read the doc for version 8.

Java offers the Year class. MySQL offers the YEAR data type. By the way, contrary to what your Question implies, the SQL standard does not define a YEAR data type as far as I know.

You might be able to pass the Java object directly. Support for the Year class is not defined in JDBC 4.2. So such behavior would be an optional feature specific to your particular JDBC driver. If your driver did offer this, I would expect it to use the PreparedStatement#setObject and ResultSet#getObject methods.

myPreparedStatement.setObject( … , Year.now() ) ;

And…

Year y = myResultSet.getObject( … , Year.class ) ;

If your JDBC driver does not offer that support for Year, the doc for MySQL says you should be able to pass either text or an integer. Here is example code for passing/receiving an integer.

Year year = Year.of( 2020 ) ;
…
pstmt.setInt( 2 , year.getValue() );

…and:

Year year = Year.of( rs.getInt( "year_" ) );

Regarding your code:

pstmt.setYear(1,business_year);

…there is no setYear method on PreparedStatement. That code will not compile.

Example app

Further down is the source code for an entire example app.

This example has commented-out code trying to use PreparedStatement#setObject and ResultSet#getObject in conjunction with the java.time.Year class.

This code fails with a lack of support for Year class when run with this JDBC driver via Maven dependency:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>

…on MySQL 8 hosted on DigitalOcean.com as a managed database service.

The two key lines in this example app are marked with // <-- java.time.Year not supported by this JDBC driver..

package work.basil.example.mysqlstuff;


import javax.sql.DataSource;
import java.sql.*;
import java.time.Instant;
import java.time.Year;
import java.util.Objects;

public class App
{
    // Member fields.

    public static void main ( String[] args )
    {
        System.out.println( "Hello world. " );
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        System.out.println( "INFO - Starting demo method. " + Instant.now() );

        DataSource dataSource = this.configureDataSource();
        this.dropTable( dataSource );
        this.createTable( dataSource );
        this.insertRow( dataSource );
        this.dumpTable( dataSource );

        System.out.println( "INFO - Done with demo method. " + Instant.now() );
    }

    private void dropTable ( DataSource dataSource )
    {
        System.out.println( "INFO - `dropTable` method. " + Instant.now() );
        try ( Connection conn = dataSource.getConnection() )
        {
            String sql = """
                         DROP TABLE IF EXISTS event_
                         ;
                         """;
            System.out.println( "sql:  \n" + sql );
            try ( Statement stmt = conn.createStatement() )
            {
                stmt.execute( sql );
            }
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
    }

    private void createTable ( DataSource dataSource )
    {
        System.out.println( "INFO - `createTable` method. " + Instant.now() );
        try ( Connection conn = dataSource.getConnection() )
        {
            String sql = """
                         CREATE TABLE IF NOT EXISTS event_
                            ( 
                               id_ INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,  -- ⬅ `identity` = auto-incrementing integer number.
                               title_ VARCHAR ( 30 ) NOT NULL ,
                               year_ YEAR NOT NULL 
                             )
                         ;
                         """;
            System.out.println( "sql:  \n" + sql );
            try ( Statement stmt = conn.createStatement() ; )
            {
                stmt.execute( sql );
            }
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
    }


    private void insertRow ( DataSource dataSource )
    {
        System.out.println( "INFO - `insertRow` method. " + Instant.now() );
        String sql = """
                     INSERT INTO event_ ( title_ , year_ )
                     VALUES ( ? , ? )
                     ;
                     """;
        try (
                Connection conn = dataSource.getConnection() ;
                PreparedStatement pstmt = conn.prepareStatement( sql ) ;
        )
        {
            pstmt.setString( 1 , "zero" );
//            pstmt.setObject( 2 , Year.of( 2020 ) );  // <-- java.time.Year not supported by this JDBC driver.
            pstmt.setInt( 2 , Year.of( 2020 ).getValue() );
            pstmt.executeUpdate();

            pstmt.setString( 1 , "one" );
            pstmt.setInt( 2 , Year.of( 2021 ).getValue() );
            pstmt.executeUpdate();

            pstmt.setString( 1 , "two" );
            pstmt.setInt( 2 , Year.of( 2022 ).getValue() );
            pstmt.executeUpdate();
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
    }

    private void dumpTable ( DataSource dataSource )
    {
        System.out.println( "INFO - `dumpTable` method. " + Instant.now() );

        String sql = "SELECT * FROM event_ ;";
        try (
                Connection conn = dataSource.getConnection() ;
                Statement stmt = conn.createStatement() ;
                ResultSet rs = stmt.executeQuery( sql ) ;
        )
        {
            System.out.println( "-------|  event_ table  |--------------------" );
            while ( rs.next() )
            {
                //Retrieve by column name
                int id = rs.getInt( "id_" );
                String title = rs.getString( "title_" );
//                Year year = rs.getObject( "year_" , Year.class );     // <-- java.time.Year not supported by this JDBC driver.
                Year year = Year.of( rs.getInt( "year_" ) );

                System.out.println( "id_=" + id + " | title_=" + title + " | year_=" + year );
            }
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
    }

    private DataSource configureDataSource ( )
    {
        System.out.println( "INFO - `configureDataSource` method. " + Instant.now() );

        com.mysql.cj.jdbc.MysqlDataSource dataSource = Objects.requireNonNull( new com.mysql.cj.jdbc.MysqlDataSource() );  // Implementation of `DataSource` bundled with H2.
        dataSource.setServerName( "db-mysql-sfo3-422-do-user-8982-1.x.db.ondigitalocean.com" );
        dataSource.setPortNumber( 24_090 );
        dataSource.setDatabaseName( "defaultdb" );
        dataSource.setUser( "scott" );
        dataSource.setPassword( "tiger" );
        return dataSource;
    }
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • it worked by setting it to pstmt.setShort() – Shhh_8279 Feb 28 '21 at 21:03
  • Did you try `setObject`? That is the current avenue by which we exchange *java.time* objects per JDBC 4.2 and 4.3. If if does work, I’d like to edit this Answer to say so definitely rather than speculatively. And if `setObject` does work, please state exactly what JDBC driver you are using, and what version. – Basil Bourque Feb 28 '21 at 21:06
  • yes when i will try i will let you know thank you – Shhh_8279 Mar 01 '21 at 08:51