Ошибка в коде JDBC, вызывающем хранимую функцию, которая возвращает значение

Я пытаюсь напечатать возвращаемое значение хранимой в MySQL функции из кода JDBC, который выглядит следующим образом (я использую MySQL Server 5.7.13):

package jdbc;

import java.sql.DriverManager;
import java.sql.*;
import java.util.Scanner;


public class CallableStatementsCallingFunctions {
    public static void main(String... syrt)
    {
      try
     {
        try
        {                
            Class.forName("com.mysql.jdbc.Driver");
        }
        catch(ClassNotFoundException e)
        {
          System.out.println("Error(class): "+ e);
        }
        try
        {
         Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/collablestatement","root","mysql") ;
         CallableStatement cs = conn.prepareCall("{call ?:=getBalance1(?)}");
         String s = new Scanner(System.in).nextLine();
         cs.registerOutParameter(1,Types.INTEGER);
         cs.setInt(2,Integer.parseInt(s));             
         cs.execute();
         System.out.println("Account number :" + cs.getInt(1));
         conn.close();
        } 
        catch(SQLException e)
        {
          System.out.println("Error(SQL) : "+e);
        }
    }
    catch(Exception e)
    {
      System.out.println("Error(Fro outer try) : "+ e);
    }
}

}

здесь показана хранимая функция getBalance1(acno)

getBalance(acno numeric)

мой вывод кода показан здесь

вывод jdbc

Я получаю вывод команды SQL, но в JDBC я получаю и SQLException говорю, что

параметр 1 не является выходным параметром

Я знаю, что параметр 1 использовался в качестве заполнителя возвращаемого значения из функции в коде jdbc. В prepareCall я тоже попробовал синтаксис - {?:= call getBalance1(?)} , но даже тогда получил такое же Exception.

Почему я получаю исключение?


person user404    schedule 31.07.2016    source источник
comment
быстрая догадка: cs.getString(1);   -  person Mohammadreza Khatami    schedule 31.07.2016


Ответы (2)


Я думаю, что получаю SQLException, потому что я использую jdk1.8.xx, в котором синтаксис вызова хранимой функции отличается. Проблема решилась заменой оператора

CallableStatement cs = conn.prepareCall("{call ?:=getBalance1(?)}");

в коде с

CallableStatement cs = conn.prepareCall("{? = call getBalance1(?)}");

Синтаксис вызова функции в методе prepareCall() в качестве параметра: здесь.

person user404    schedule 31.07.2016
comment
Я не думаю, что синтаксис каким-либо образом изменился в Java 8. У вас просто была опечатка (лишнее двоеточие + неуместное ключевое слово call) в исходном утверждении. - person Mick Mnemonic; 01.08.2016

getBalance1() - это MySQL FUNCTION, а не PROCEDURE, поэтому я не ожидаю, что использование JDBC CallableStatement будет применимо.

Даже в тесте консоли MySQL вы используете

select getBalance1(103)

поэтому вам просто нужно сделать то же самое в коде Java, используя PreparedStatement:

PreparedStatement ps = conn.prepareStatement("select getBalance1(?)");
ps.setInt(1) = 103;
ResultSet rs = ps.executeQuery();
rs.next();
Double bal = rs.getDouble(1);

(Следует отметить, что, поскольку «баланс», по-видимому, относится к «деньгам», REAL не является хорошим выбором для типа столбца; подробности здесь .)

person Gord Thompson    schedule 31.07.2016
comment
Я получаю то, что вы написали здесь. Но тогда для чего будет использоваться интерфейс CallableStatement, если вместо этого я буду использовать PreparedStatement ?? Я пытаюсь получить результаты, используя CallableStatement, так как тогда у меня могут возникнуть десятки проблем. - person user404; 31.07.2016
comment
CallableStatement — это способ запуска хранимых процедур JDBC, которые создаются в MySQL с помощью CREATE PROCEDURE и вызываются в MySQL с помощью CALL procedurename. Вы использовали CREATE FUNCTION для создания определяемой пользователем функции, которая обычно вызывается включением ее в выражение, например, как часть оператора SELECT. - person Gord Thompson; 31.07.2016
comment
На самом деле вы также можете вызывать SQL FUNCTIONs с CallableStatements. Синтаксис JDBC для этого — myConnection.prepareCall("{? = call my_function(?)}");, как показано в ответе, автором которого является OP. - person Mick Mnemonic; 01.08.2016