Home > database >  Java String can't be converted to MySQL char
Java String can't be converted to MySQL char

Time:11-29

I'm doing a Java program that has to interact with a MySQL database, and I'm trying to delete a row of a table from a query in Java.

The problem is that when I try to convert a String in Java, "2021/2022" to char(9) I get an error that says that data is too long for column. Can anyone help?

This is the method that should delete the row:

public boolean borrarMatricula(Connection conn, int alumno, int profesor, int asignatura, 
        String c){
    
    boolean borrado = false;
    
    String drop = "DROP PROCEDURE IF EXISTS DELETE_ENROLLMENT";
    String rutina = "CREATE PROCEDURE DELETE_ENROLLMENT(IN alumno double(4,0), "
              "IN profesor double(2,0), IN asignatura double(3,0), IN c char(9))"
                    "BEGIN "
                    "DELETE FROM MATRICULAS WHERE codigoAlumno=alumno and "
              "codigoProfesor=profesor and codigoAsignatura=asignatura and curso=c;"
                    "END";
    
    try{
        Statement s = conn.createStatement();
        s.execute(drop);
        s.execute(rutina);
        
        CallableStatement cs=conn.prepareCall("{call DELETE_ENROLLMENT("  
                alumno   ","   profesor   ","   asignatura   ","   c   ")}");
        cs.execute();
        
        borrado = true;

    }
    catch(SQLException e){
        Vista.muestraErrorSQL(e);
    }
    catch(Exception e){
        e.printStackTrace(System.err);
    }
    
    return(borrado);
}

"Curso" is defined as a char(9), and the String I'm using is 2021/2022

CodePudding user response:

What happened is that you are concatenating Java variables into your CALL statement:

    CallableStatement cs=conn.prepareCall("{call DELETE_ENROLLMENT("  
            alumno   ","   profesor   ","   asignatura   ","   c   ")}");

So it runs a CALL statement as though you formatted it like this:

mysql> call delete_enrollment(1, 1, 1, 2021/2022);
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
 --------- ------ ---------------------------------------- 
| Level   | Code | Message                                |
 --------- ------ ---------------------------------------- 
| Warning | 1265 | Data truncated for column 'c' at row 1 |
 --------- ------ ---------------------------------------- 

In Java, warnings are promoted to errors. The value is not the string '2021/2022', but a floating-point value which is the quotient of 2021/2022, or approximately 0.9995. It results in a warning when you try to use a floating-point value as a string.

If you used an actual quoted string, there is no warning:

mysql> call delete_enrollment(1, 1, 1, '2021/2022');
Query OK, 0 rows affected (0.00 sec)

But you should just avoid using string concatenation. You're already using a prepared statement, so you should use bound parameters:

    CallableStatement cs=conn.prepareCall("{call DELETE_ENROLLMENT(?, ?, ?, ?)}");
    cs.setDouble(1, alumno);
    cs.setDouble(2, profesor);
    cs.setDouble(3, asignatura);
    cs.setString(4, c);
    cs.execute();

Using parameters instead of string-concatenation is one of the most important reasons to use prepared statements. It makes your code more secure and less error-prone, and it's easier to read and write the code.

See also: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-statements-callable.html

  • Related