繁体   English   中英

具有命名绑定的 CallableStatement 导致 PLS-00306:错误的参数数量或类型

[英]CallableStatement with Named binding leads to PLS-00306: wrong number or types of arguments

我们需要在我们的 java8 项目中更新 oracle 驱动程序。 我们将其从 ojdbc6 更改为 ojdbc8 19.3.0.0 因此我们遇到了这样的异常

Caused by: java.sql.SQLException: ORA-06550: line 1, column 18:
PLS-00306: wrong number or types of arguments in call to 'MAKEWORK'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

执行以下代码:

try (CallableStatement cs = con.prepareCall("{call :result := CORE.PKG.makeWork(arg1=>:arg1, arg2=>:arg2)}")) {
    cs.setString("arg1", javaArg1);
    cs.setInt("arg2", javaArg2);
    cs.registerOutParameter("result", Types.ARRAY, CommonTypeNameConstant.T_TABLE_OF_NUMBERS_TYPE);
    cs.execute();
    Array result = (Array) cs.getObject("result");

它只发生在函数中。 我的意思是,如果CORE.PKG.makeWork是一个过程,代码就可以工作:

try (CallableStatement cs = con.prepareCall("{call CORE.PKG.makeWork(arg1=>:arg1, arg2=>:arg2)}")) {
    cs.setString("arg1", javaArg1);
    cs.setInt("arg2", javaArg2);
    cs.execute();

该问题可以通过将 oracle 脚本从命名绑定迁移到序数绑定来解决:

try (CallableStatement cs = con.prepareCall("{? = call CORE.PKG.makeWork(arg1=>?, arg2=>?)}")) {
    cs.registerOutParameter(1, Types.ARRAY, CommonTypeNameConstant.T_TABLE_OF_NUMBERS_TYPE);
    cs.setObject(2, javaArg1);
    cs.setObject(3, javaArg2);
    cs.execute();
    Array result = (Array) cs.getObject(1);

但是我们希望将 Named 绑定保留在项目中,因为 Ordinal 绑定倾向于开发人员在列出参数时出现顺序错误 + 我们有很多脚本要重写。

为什么输出参数的命名绑定不能与新版本的驱动程序一起使用?

文档来看,您仍然可以在 sql 中使用命名绑定,但必须按位置为它们设置值:

try (CallableStatement cs = con.prepareCall("{call CORE.PKG.makeWork(arg1=>:arg1, arg2=>:arg2)}")) {
    cs.setString(1, javaArg1);
    cs.setInt(2, javaArg2);
    cs.execute();

或者您可以使用oracle.jdbc.OracleCallableStatement按名称设置绑定值,但必须将所有“:params”替换为“?”:

仅当所有绑定都是过程或函数参数时,才能使用 setXXX(String,...) 和 registerOutParameter(String,...) 方法。 该语句不能包含其他绑定,并且参数绑定必须用问号 (?) 表示,而不是 :XX

try (CallableStatement cs = con.prepareCall("{call CORE.PKG.makeWork(arg1=>?, arg2=>?)}")) {
    cs.setString("arg1", javaArg1);
    cs.setInt("arg2", javaArg2);
    cs.execute();

或者您可以使用 Spring JDBC 中的NamedParameterJdbcTemplate

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM