简体   繁体   中英

Java String can't be converted to MySQL char

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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