簡體   English   中英

使用帶有布爾 IN 參數的 CallableStatement 在 Java 中調用 Oracle PL/SQL 過程會產生 PLS-00306 oracle 錯誤:

[英]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();

除了isEUProductboolean之外,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 驅動程序不支持將布爾值傳遞到存儲過程中......是的,我不是編造的 :)

PL/SQL 存儲過程中的布爾參數

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

我將演示一個帶有INOUT 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM