使用带有布尔 IN 参数的 CallableStatement 在 Java 中调用 Oracle PL/SQL 过程会得到 PLS-00306 预言机错误:

2022-09-05 00:38:23

我在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();

Java 变量的类型都不同,但 .每当我运行上述程序时,我都会收到以下错误:StringisEUProductboolean

PLS-00306: wrong number or types of arguments in call to validate_product ORA-06550: line 1, column 7: PL/SQL: Statement ignored"

我必须调试程序一百次,但一切似乎都是正确的类型,参数的数量是正确的。

我完全陷入了我做错了什么的困境。谷歌搜索了一下,我怀疑也许我没有正确设置布尔参数。

有什么想法吗?


答案 1

当我们遇到这种情况时,我感到惊讶,但是Oracle JDBC驱动程序不支持将布尔值传递到存储过程中。,我不是在编造:)

PL/SQL 存储过程中的布尔参数

JDBC 驱动程序不支持将布尔参数传递给 PL/SQL 存储过程。如果 PL/SQL 过程包含布尔值,则可以通过将 PL/SQL 过程包装为第二个 PL/SQL 过程来解决限制,该过程接受参数作为 INT 并将其传递给第一个存储过程。调用第二个过程时,服务器执行从 INT 到布尔值的转换。


答案 2

对于该限制,有一个简单的解决方法,它不需要包装器过程,只需将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); 

推荐