MySQL Connector/J CallableStatement - 参数不是 OUT 参数

问题描述 投票:0回答:1

尝试迁移到 MySQL Connector/J 8.1.0 和我的

CallableStatement
代码在版本 5.1.49 下工作正常失败,并显示:

SQLException: Parameter number 2 is not an OUT parameter

程序:

CREATE PROCEDURE get_system_setting(IN p_setting VARCHAR(200), OUT message_out VARCHAR(200))
BEGIN
  SELECT setting, value, message_out FROM SYSTEM_SETTING WHERE setting = p_setting;
END;

Java 代码示例:

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class CallableTest {

  /* MySQL Connector/J 8.1.0 (fails on all 8.*.* versions) */
  private static final String DB_DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";

  /* MySQL Connector/J 5.1.49 - comment line above and uncomment next line to use v5 */
  //private static final String DB_DRIVER_CLASS = "com.mysql.jdbc.Driver";

  private static final String DB_URL = "jdbc:mysql://localhost:3306/DB_NAME?useSSL=false";
  private static final String DB_USERNAME = "user";
  private static final String DB_PASSWORD = "password";

  public static Connection getConnection() {
    Connection conn = null;
    try {
      Class.forName(DB_DRIVER_CLASS);
      conn = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
     e.printStackTrace();
    }
    return conn;
  }

  public static void main(String[] args) {
    Connection conn = null;
    CallableStatement cs = null;

    try {
      conn = CallableTest.getConnection();
      cs = conn.prepareCall("{call DB_NAME.get_system_setting(?, ?)}");
      cs.setString(1, "CONNECT_TIMEOUT");
      cs.registerOutParameter(2, Types.VARCHAR); // <-- Fails here

      cs.execute();
      String message = cs.getString(2);
      if(message != null) {
        System.out.printf("out parameter: %s\n",  message);
      } else {
        ResultSet rs = cs.getResultSet();
        boolean rowsReturned = ((rs != null) && rs.next());
        if (rowsReturned) {
          String setting = rs.getString("setting");
          String value = rs.getString("value");
          System.out.printf("setting: %s, value: %s\n", setting, value);
        }
     }
   } catch(Exception e) {
     e.printStackTrace();
   } finally {
     try {
       cs.close();
       conn.close();
     } catch (SQLException e) {
       e.printStackTrace();
     }
   }
  }
}

使用 8.1.0 和所有 8.0.* 版本的连接器/j 时,上述操作会失败

java -cp .:mysql-connector-j-8.1.0.jar CallableTest

java.sql.SQLException: Parameter number 2 is not an OUT parameter
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:98)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:90)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:64)
    at com.mysql.cj.jdbc.CallableStatement.checkIsOutputParam(CallableStatement.java:645)
    at com.mysql.cj.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1717)
    at com.mysql.cj.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1725)
    at CallableTest.main(CallableTest.java:49)

但适用于 5.1.49

java -cp .:mysql-connector-java-5.1.49.jar CallableTest

setting: CONNECT_TIMEOUT, value: 10000

尝试了命名参数和索引参数。查看 Connector/J 文档,找不到任何对版本之间 CallableStatement 的特定更改的引用。

环境

  • 连接器/J:8.1.0
  • MySQL:8.0.33
  • Java:1.8.0_331
mysql jdbc callable-statement connector-j
1个回答
0
投票

事实证明,该数据库模式中有一个与过程同名的函数...MySQL 允许使用相同的对象名称来声明函数和过程。似乎不应该允许这种情况,因为其他数据库就是这种情况。此外,错误消息有些误导性。与 Oracle 一起打开了错误报告

© www.soinside.com 2019 - 2024. All rights reserved.