![](/img/trans.png)
[英]Wrong type or number of parameters when calling a PL/SQL function using Java. PLS-00306 error
[英]Calling an Oracle PL/SQL procedure in Java using a CallableStatement with a boolean IN parameter gives an PLS-00306 oracle error:
我在 Oracle 11g 上有一个 pl/sql 过程,它具有以下参数:
PROCEDURE validate_product
( product_id_in IN varchar2 ,
username_in in varchar2,
source_in varchar2,
source_id_in varchar2 ,
isEuProduct in boolean ,
error_code out varchar2,
product_type out varchar2
)
我正在尝试使用以下代码从 java 内部调用上述存储过程:
cstmt = getConnection().prepareCall("begin " + DBUtil.SCHEMANAME + ".PRODUCT_UTILITIES.validate_product(:1,:2,:3,:4,:5,:6,:7); end;");
cstmt.registerOutParameter(6, Types.CHAR);
cstmt.registerOutParameter(7, Types.CHAR);
cstmt.setString(1, productId);
cstmt.setString(2, username);
cstmt.setString(3, sourceName);
cstmt.setString(4, sourceId);
cstmt.setBoolean(5, isEUProduct);
cstmt.execute();
除了isEUProduct
是boolean
之外,java 变量的类型都是String
。 每当我运行上述程序时,都会出现以下错误:
PLS-00306: wrong number or types of arguments in call to validate_product ORA-06550: line 1, column 7: PL/SQL: Statement ignored"
我必须调试程序一百次,但一切似乎都是正确的类型,参数的数量也是正确的。
我完全不知道我做错了什么。 用谷歌搜索后,我怀疑我可能没有正确设置布尔参数。
有任何想法吗?
当我们遇到这个问题时,我感到很惊讶,但是 Oracle JDBC 驱动程序不支持将布尔值传递到存储过程中......是的,我不是编造的 :)
JDBC 驱动程序不支持将 BOOLEAN 参数传递给 PL/SQL 存储过程。 如果 PL/SQL 过程包含 BOOLEAN 值,您可以通过用第二个 PL/SQL 过程包装 PL/SQL 过程来解决限制,该过程接受参数作为 INT 并将其传递给第一个存储过程。 当调用第二个过程时,服务器执行从 INT 到 BOOLEAN 的转换。
该限制有一个简单的解决方法,它不需要包装过程,只需将 PL/SQL 中的布尔参数包装在CASE
语句中,并使用整数进行绑定:
stmt = connection.prepareCall("begin"
+" booleanFunc(par_bool => (CASE ? WHEN 1 THEN TRUE ELSE FALSE END)); "
+"end;"
);
// now bind integer, 1 = true, 0 = false
stmt.setInt(1, 0); // example for false
如果您的方法使用布尔值,您可以在绑定期间以相反的方式包装 Integer,例如:
// now bind integer, 1 = true, 0 = false
stmt.setInt(1, myBool ? 1 : 0);
我认为这是问题
cstmt.registerOutParameter(6, Types.CHAR);
cstmt.registerOutParameter(7, Types.CHAR);
您如上所述从 java 调用,但是您在程序 out 参数中声明为varchar2
,这意味着数据类型不匹配。
试试这个代码,
cstmt.registerOutParameter(6, Types.VARCHAR);
cstmt.registerOutParameter(7, Types.VARCHAR);
我希望这会奏效..
我怀疑 out 语句可能需要修改以下内容(因为 out 参数的类型在过程中是 varchar2):-
cstmt.registerOutParameter(6, Types.VARCHAR);
cstmt.registerOutParameter(7, Types.VARCHAR);
但是,如果这不起作用,请尝试将 prepareCall 语句修改为以下内容:-
cstmt = getConnection().prepareCall("{call " + DBUtil.SCHEMANAME + ".PRODUCT_UTILITIES.validate_product(?,?,?,?,?,?,?)}");
从 Oracle 12.2 开始,有一个JDBC Support for Binding PLSQL_BOOLEAN
我将演示一个带有IN
和OUT
BOOLEAN
参数的简单过程
create or replace PROCEDURE proc_C (flag_in BOOLEAN, flag_out OUT BOOLEAN) as
begin
flag_out := flag_in;
end;
/
不幸的是,不能直接使用setBoolean
来绑定第一个参数。
在这种情况下,驱动程序Version 19.3.0.0.0
返回PLS-00306: wrong number or types of arguments in call to 'PROC_C'
解决方法很简单,使用setObject(1,true,oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)
整个例子
stmt = con.prepareCall("{ call proc_C(?,?)}")
stmt.setObject(1,false,oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)
stmt.registerOutParameter(2, oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)
stmt.execute()
flag = stmt.getBoolean(2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.