【问题标题】:Java String can't be converted to MySQL charJava String 无法转换为 MySQL char
【发布时间】:2021-11-28 14:27:50
【问题描述】:

我正在编写一个必须与 MySQL 数据库交互的 Java 程序,并且我正在尝试从 Java 查询中删除表中的一行。

问题是,当我尝试将 Java 中的字符串“2021/2022”转换为 char(9) 时,我收到一条错误消息,指出数据对于列而言太长。有人可以帮忙吗?

这是应该删除行的方法:

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”定义为char(9),我使用的String是2021/2022

【问题讨论】:

  • 你能分享一个你使用的代码以及你用来创建表的sql吗?
  • 建议在问题中也包含相关代码,或者最好包含minimal and reproducible example
  • @MirekPluta 抱歉,第一次发帖。我已经编辑过了
  • @esQmo_ 抱歉,第一次发帖。我已经编辑过了

标签: java mysql


【解决方案1】:

发生的情况是您将 Java 变量连接到 CALL 语句中:

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

所以它运行一个 CALL 语句,就好像你这样格式化它:

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 |
+---------+------+----------------------------------------+

在 Java 中,警告被提升为错误。该值不是字符串'2021/2022',而是一个浮点值,它是 2021/2022 的商,即大约 0.9995。当您尝试将浮点值用作字符串时,它会导致警告。

如果您使用了实际的引号字符串,则不会出现警告:

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

但是你应该避免使用字符串连接。您已经在使用准备好的语句,因此您应该使用绑定参数:

    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();

使用参数而不是字符串连接是使用预准备语句的最重要原因之一。它使您的代码更安全,更不容易出错,并且更易于阅读和编写代码。

另请参阅:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-statements-callable.html

【讨论】:

  • 非常感谢您的回答!我对从 Java 与 MySQL 交互还是很陌生,所以我完全忽略了这种可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-04
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多