1

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

3
  • Can you share a code that you use for that and also an sql that you used to create a table? Commented Nov 28, 2021 at 14:38
  • It's advisable include the relevant code into the question as well, or better include a minimal and reproducible example Commented Nov 28, 2021 at 14:38
  • @MirekPluta sorry, first time posting. I already edited it Commented Nov 28, 2021 at 14:58

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.