如何从Java调用MySQL存储函数?

时间:2017-06-11 06:41:40

标签: java mysql stored-functions

我的本​​地有Sakila Sample Database,我试图从Java调用get_customer_balance函数。

这是我的代码:

double callableStatementFunctionCallExample(final int customerId) throws SQLException {
    double customerBalance = -1;

    final Connection connection = DriverManager.getConnection(url, user, pass);

    final CallableStatement callableStatement = connection.prepareCall("{CALL ? = get_customer_balance(?, ?)}");
    callableStatement.registerOutParameter(1, customerBalance);
    callableStatement.setInt(2, customerId);
    final java.sql.Date date = new Date(Calendar.getInstance().getTimeInMillis());
    callableStatement.setDate(3, date);

    callableStatement.execute();
    return customerBalance;
}

导致:

Exception in thread "main" java.sql.SQLException: Parameter number 1 is not an OUT parameter.

所以我替换了这句话..

callableStatement.registerOutParameter(1, customerBalance);

与..

callableStatement.setDouble(1, customerBalance);

导致:

Exception in thread "main" java.sql.SQLException: Parameter p_film_count is not registered as an output parameter.

所以显然我需要注册一个out parameter,但是怎么样?为什么我的第一种方法错了?

2 个答案:

答案 0 :(得分:1)

方法的签名是void registerOutParameter(int parameterIndex, int sqlType),其中sqlType被描述为"由java.sql.Types"定义的JDBC类型代码。

这意味着您的电话应该是:

callableStatement.registerOutParameter(1, Types.DOUBLE);

您可以在execute()电话后使用:

检索该值
double customerBalance = callableStatement.getDouble(1);

您使用值-1调用它,这是Types.LONGVARCHAR的值。

此外,CallableStatement的javadoc显示SQL字符串的语法为{?= call <procedure-name>[(<arg1>,<arg2>, ...)]},这意味着您的语句应为:

final CallableStatement callableStatement = connection.prepareCall("{? = CALL get_customer_balance(?, ?)}");

如果您阅读了javadoc,这两个问题都可以解决。

答案 1 :(得分:0)

在execute()之前按类型(例如整数)注册:

final CallableStatement callableStatement = connection.prepareCall("{? = call get_customer_balance(?, ?)}");

callableStatement.registerOutParameter(1, java.sql.Types.INTEGER);