![](/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.