【问题标题】:java.sql.SQLException: Parameter number X is not an OUT parameterjava.sql.SQLException:参数号 X 不是 OUT 参数
【发布时间】:2011-03-02 08:51:11
【问题描述】:

我正在努力从 MySQL 存储过程中获取结果 OUT 变量。我收到以下错误:

java.sql.SQLException: Parameter number 3 is not an OUT parameter

存储过程如下所示:

CREATE DEFINER=`cv_admin`@`localhost` PROCEDURE `CheckGameEligibility`(
   IN gID INT(10),
   IN uID INT(10),

   OUT result TINYINT(1)
)
BEGIN
    # Do lots of stuff, then eventually:
    SET result = 1;
END 

我的 java 函数接受一个字符串数组*并动态创建 CallableStatement 对象:

public static int callAndReturnResult( String sql , String[] values )
{
    int out = 0 ;
    try
    {
        // construct the SQL. Creates: CheckGameEligibility(?, ?, ?)
        sql += "(" ;

        for( int i = 0 ; i < values.length ; i++ )
        {
            sql += "?, " ;
        }
        sql += "?)" ;

        System.out.println( "callAndReturnResult("+sql+"): constructed SQL: " + sql );

        // Then the statement
        CallableStatement cstmt = DB.prepareCall( sql );
        for( int i = 0 ; i < values.length ; i++ )
        {
            System.out.println( "   " + (i+1) + ": " + values[ i ] ) ;
            cstmt.setString(i+1, values[ i ] );
        }

        System.out.println( "   " + (values.length+1) + ": ? (OUT)" ) ;
        cstmt.registerOutParameter( values.length + 1 , Types.TINYINT );
        cstmt.execute();

        out = cstmt.getInt( values.length );
        cstmt.close();
    }
    catch( Exception e )
    {
        System.out.println( "*** db trouble: callAndReturnResult(" + sql + " failed: " + e );
        e.printStackTrace() ;
    }
    return out ;
}

*) 我想我应该使用 int 数组而不是字符串数组,但这似乎不是错误消息的内容。

无论如何,这是它生成的输出:

callAndReturnResult(CheckGameEligibility(?, ?, ?)): constructed SQL: CheckGameEligibility(?, ?, ?)
1: 57
2: 29
3: ? (OUT)
*** db trouble: callAndReturnResult(CheckGameEligibility(?, ?, ?) failed: java.sql.SQLException: Parameter number 3 is not an OUT parameter
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
    at com.mysql.jdbc.CallableStatement.checkIsOutputParam(CallableStatement.java:692)
    at com.mysql.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1847)
    at org.apache.commons.dbcp.DelegatingCallableStatement.registerOutParameter(DelegatingCallabl>eStatement.java:92)
    at Tools.callAndReturnResult(Tools.java:156)

任何想法可能是什么问题? :)

提前致谢!

【问题讨论】:

  • 我遇到了同样的错误,因为数据库中不存在该过程

标签: java mysql stored-procedures


【解决方案1】:

这里有关于如何从jdbc调用存储过程的教程:
http://java.sun.com/docs/books/tutorial/jdbc/basics/sql.html
sql格式和你的不一样。

【讨论】:

  • 谢谢,但问题不在于调用存储过程(我在代码的其他部分这样做),而在于使用 callablestatement 的带有返回变量的存储过程 :)
【解决方案2】:

我不确定为什么 Java 或 Java 的 MySQL 驱动程序不喜欢这种语法,但您是否考虑过将过程创建为 FUNCTION 而不是 RETURNS TINYINT

【讨论】:

  • 是的,我像上面那样创建它的原因是因为我想我会有更多带有类似返回变量的存储过程,所以尝试制作一个通用函数对我来说是有意义的如果你明白我的意思的话,把电话包装起来?
【解决方案3】:

我也遇到了这个异常,我发现这只是我在构造 CALL 字符串时犯的一个愚蠢的小语法错误。仔细检查您的语法是否正确。

【讨论】:

    【解决方案4】:

    对我来说同样的问题,但我修复了 Anthony 建议的语法检查,我发现我使用骆驼大小写约定调用存储过程,例如:addPaiment 并且在数据库中它被存储为 ADDPAIMENT 所以我相信 mysql没有找到存储过程。

    【讨论】:

      【解决方案5】:

      我的代码略有不同

      CallableStatement statement = connection.prepareCall("{? = call nextOperatorTransactionId()}");
      statement.registerOutParameter(1, Types.BIGINT);
      statement.execute();
      id.set(statement.getLong(1));
      

      注意括号,在我的例子中是 ?在句子的开头。不使用括号我得到了和你一样的例外

      【讨论】:

        【解决方案6】:

        尝试call CheckGameEligibility(?, ?, ?) 而不是CheckGameEligibility(?, ?, ?)。它在同样的情况下帮助了我。

        【讨论】:

          【解决方案7】:

          当您指定的过程名称与 db 中存在的实际过程不同时,我的 sql 会给出此无关异常。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-25
            • 2013-10-23
            • 2012-08-05
            • 1970-01-01
            • 2019-12-03
            • 2022-08-22
            • 1970-01-01
            • 2014-05-04
            相关资源
            最近更新 更多