Параметр не является ошибкой параметра OUT при вызове хранимой процедуры через CallableStatement

Я пытался вызвать процедуру "proc", созданную в MySQL Workbanch:

create database test_database;
use test_database;

delimiter &&
create procedure proc(inout param INT UNSIGNED)
begin
    set param = 2*param;
end&&

с помощью этого приложения:

package test;

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

public class Test {

public static void main(String[] args) {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1", "root", "root");
        connection.createStatement().execute("USE test_database");
        CallableStatement callableStatement = connection.prepareCall("{call proc(?)}");
        callableStatement.setInt(1, 5);
        callableStatement.registerOutParameter(1, java.sql.Types.INTEGER);
        ResultSet result = callableStatement.executeQuery();
        if (result.first()) {
            System.out.println(result.getInt(1));
        }            
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}}

но я всегда получаю эту ошибку:

java.sql.SQLException: Parameter number 1 is not an OUT parameter
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928)
at com.mysql.jdbc.CallableStatement.checkIsOutputParam(CallableStatement.java:695)
at com.mysql.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:2016)
at test.Test.main(Test.java:16)

Я пытался выяснить, что не так много часов, но безуспешно. Я видел много вопросов, но: это бесполезно, потому что в функции не может быть транзакции

это бесполезно, потому что когда я использую именованный параметр, выбрасывается NullPointerEx (почему??)

это бесполезно, потому что процедура существует и не выдает никаких исключений когда я использую только параметр IN, но с INOUT или OUT возникает упомянутое исключение

это бесполезно, потому что я не вижу очевидной ошибки

это бесполезно, потому что обновление соединителя JDBC не помогло< /а>

Итак, мой вопрос прост: есть идеи, что может быть не так?


person BrooksWasHere    schedule 22.08.2014    source источник
comment
Я бы попробовал две вещи: (1) использовать строку подключения jdbc:mysql://127.0.0.1/test_database и удалить вызов execute("USE test_database"). (2) Поменяйте местами линии setInt и registerOutParameter.   -  person Sergey Kalinichenko    schedule 22.08.2014
comment
Чтобы добавить к предложениям @dasblinkenlight: возможно, попробуйте .execute() вместо .executeQuery(). Руководства, которые я просмотрел, используют .execute(), но я не уверен, что это связано с вашей ошибкой, но это может быть ошибка в будущем, с которой вы столкнетесь.   -  person Xabster    schedule 22.08.2014
comment
@dasblinkenlight О, чувак, ты сделал мой день! Спасибо. Могу я спросить вас, добавьте свой комментарий в качестве ответа. Я приму это как лучший ответ. И если вы знаете, в чем разница между USE имя_базы_данных; оператор и определите имя базы данных в URL-адресе, пожалуйста, напишите его, чтобы ответить :)   -  person BrooksWasHere    schedule 22.08.2014


Ответы (1)


Я бы попробовал две вещи:

  1. Используйте строку подключения "jdbc:mysql://127.0.0.1/test_database" и удалите вызов execute("USE test_database")
  2. Поменяйте местами строки setInt и registerOutParameter.

В общем, выполнение USE test_database должно быть нормальным, но Документация MySQL явно предостерегает от его использования:

Всегда используйте метод Connection.setCatalog() для указания нужной базы данных в приложениях JDBC, а не оператор USE database.

Хотя контекст немного отличается, кажется, что тот же совет применим и к вашей ситуации.

person Sergey Kalinichenko    schedule 22.08.2014