簡體   English   中英

使用dbms_sql.bind_variable函數時ORA-1006綁定變量不存在

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

在這里, cntAcctcustAcctNumbercardNoCodeVarchar2

上面的代碼在大多數情況下都可以正常工作,但很少會在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.

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