[英]ORA-1006 bind variable doesn't exists while using dbms_sql.bind_variable function
我收到ORA-1006錯誤,“綁定變量不存在”
下面是我的代碼片段
create or replace procedure bindFailure(In_cntAcct, In_custAcct, In_CardNo, In_Code) AS
txnHdl INTEGER;
begin
txnHdl := dbms_sql.open_cursor;
sqlStmt := 'select * from txn t'
|| ' where t.cntAcct = :IN_CNTACCT '
|| ' and t.custAcct = :IN_CUSTACCT '
|| ' and t.cardNo = :IN_CARDNO '
|| ' and t.Code = :IN_CODE ';
dbms_sql.parse(txhHdl, sqlStmt, DBMS_SQL.NATIVE);
dbms_sql.bind_variable(txnHdl, ':IN_CNTACCT' , In_cntAcct);
dbms_sql.bind_variable(txnHdl, ':IN_CUSTACCT' , In_custAcct);
dbms_sql.bind_variable(txnHdl, ':IN_CARDNO' , In_CardNo);
dbms_sql.bind_variable(txnHdl, ':IN_CODE' , In_Code);
dbms_sql.execute(txnHdl);
.... /* In actual code we use fetch rows */
end;
/
在這里, cntAcct
, custAcct
是Number
, cardNo
和Code
的Varchar2
上面的代碼在大多數情況下都可以正常工作,但很少會在100K中一次失敗,並顯示錯誤“綁定變量不存在”。
如果我們采用相同的輸入和過程,則效果很好。 我不知道為什么會有這個問題。 請幫我。
注意:以上代碼為摘要,如果有任何拼寫錯誤,我將手動輸入,請忽略。
謝謝Premchand C
解決方法是,避免使用動態SQL。 無需在SELECT列表中編碼星號(“ *
”),而是指定需要返回的列名。 並在SQL文本中包含參數變量; Oracle會為您自動綁定。
CREATE OR REPLACE PROCEDURE ...
IS
CURSOR lcsr_txn IS
SELECT t.cntAcct
, t.custAcct
, t.cardNo
, t.Code
FROM txn t
WHERE t.cntAcct = IN_cntAcct
AND t.custAcct = IN_custAcct
AND t.cardNo = IN_cardNo
AND t.Code = IN_Code
;
BEGIN
FOR lrec IN lcsr_txn LOOP
-- code to process rows goes here e.g.
DBMS_OUTPUT.PUT_LINE("cntAcct="||lrec.cntAcct);
END LOOP;
END;
原始答案
那是頭擦傷。 這段代碼顯然沒有錯。 (鑒於該過程大多數情況下都有效,因此我將假定已指定參數上的數據類型,並且這些都是IN參數。)
可以想象解析可以工作,您可以返回一個游標句柄,但是在所有對bind_variable的調用完成之前,游標就變得無效了。 但是我認為這是ORA-1006以外的例外。
如果txnHdl以某種方式被喚醒並指向另一個游標,則可以在錯誤的游標上調用bind_variable
過程時看到ORA-1006異常被引發。 (但是那將是Oracle代碼中的一個嚴重錯誤,而不是您的過程中的錯誤。但是我從未遇到過該錯誤,也從未在任何MySQL中檢查類似的東西。
為了調試它,因為它很少發生,因此我將在Oracle支持下打開一個案例,看看是否有可能在引發異常ORA-1006時收集跟蹤/轉儲。 (我以前從來沒有做過SET EVENT;我什至不知道這是否可能或受支持,這可能是“客戶端”異常,但是在服務器上執行的PL / SQL塊中,我會認為它會可用。但是我會這樣做,尤其是在Oracle支持的指導下在生產數據庫服務器上。)
問:
您如何確定是bind_variable
異常的過程中的bind_variable
調用。 該ORA-1006異常是否包含在ORA-06502異常中? (我希望是這樣。如果不是,那么它實際上可能是將變量綁定到引發異常的過程的JDBC會話。)
我很想為該過程的每個輸入參數創建一個本地過程變量,然后將輸入參數分配給該本地過程變量。 我也很想放入EXCEPTION處理程序,因此我可以審計問題:
CREATE OR REPLACE PROCEDURE bindFailure
( In_cntAcct NUMBER
, In_custAcct NUMBER
, In_CardNo VARCHAR2
, In_Code VARCHAR2
) AS
txnHdl INTEGER;
xn_cntacct txn.cntAcct%TYPE;
xn_custacct txn.custAcct%TYPE;
xn_cardno txn.cardNo%TYPE;
xn_code txn.Code%TYPE;
bind_variable_does_not_exist EXCEPTION;
PRAGMA EXCEPTION_INIT (bind_variable_does_not_exist, 1006);
BEGIN
xn_cntAcct := IN_CntAcct;
xn_custAcct := IN_CustAcct;
xn_cardno := IN_CardNo;
xn_code := IN_Code;
txnHdl := dbms_sql.open_cursor;
sqlStmt := 'select * from txn t'
|| ' where t.cntAcct = :IN_CNTACCT '
|| ' and t.custAcct = :IN_CUSTACCT '
|| ' and t.cardNo = :IN_CARDNO '
|| ' and t.Code = :IN_CODE ';
dbms_sql.parse(txnHdl, sqlStmt, DBMS_SQL.NATIVE);
dbms_sql.bind_variable(txnHdl, ':IN_CNTACCT' , xn_cntacct);
dbms_sql.bind_variable(txnHdl, ':IN_CUSTACCT' , xn_custacct);
EXCEPTION
WHEN bind_variable_does_not_exist THEN
-- auditing here
RAISE;
WHEN OTHERS THEN
RAISE;
END;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.