1

I'm getting ORA-1006 error, "bind variable doesn't exists"

Below is my snippet of code

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;
/

Here, cntAcct, custAcct are Number, cardNo and Code are Varchar2

Most of the time above code works fine, but rarely once in 100K this code failed with error "binding variable doesn't exists".

If we take the same input and process, it works fine. I'm not able to figure out, why we are having this issue. Please help me on this.

Note: above code is snippet and i manually typed if any typo issue please ignore.

Thank you, Premchand C

5
  • 1
    On which line is the code failing? Commented Jul 23, 2013 at 19:19
  • in one of the dbms_sql.bind_variable function Commented Jul 23, 2013 at 19:30
  • Maybe it's only a typing error, but in this snippet you parse using txhHdl variable, but binds use txnHdl Commented Jul 23, 2013 at 20:22
  • How often do you commit or rollback the associated transaction? And which of the DBMS_SQL.BIND_VARIABLE calls fails? ALSO - I suspect it's just a typo, but in the DBMS_SQL.PARSE call you use a variable called txhHdl which elsewhere is txnHdl. Commented Jul 23, 2013 at 21:25
  • Hi Jarvis, yes thats a typo. Any one of them is failing its very random. we receive everyday approx 100K txn once in a 2 or 3 days we are getting this failure. Commented Jul 24, 2013 at 7:56

1 Answer 1

1

As a workaround, you could avoid using dynamic SQL. Instead of coding the asterisk ("*") in the SELECT list, specify the column names you need returned. And include the argument variables in the SQL text; Oracle does automatic binds for you.

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;

ORIGINAL ANSWER

That's a head scratcher. There's nothing obviously wrong in this code. (Given that the procedure works most of the time, I'm going to assume that the datatypes on the parameters are specified, and that these are all IN parameters.)

It's conceivable that the parse works, you get a cursor handle back, but the cursor is getting invalidated before all of the calls to bind_variable complete. But I would think that would be an exception other that ORA-1006.

If txnHdl is somehow getting wonked up and pointed to a different cursor, I could see an ORA-1006 exception being raised, when the bind_variable procedure gets called on the wrong cursor. (But that would be a serious bug in the Oracle code, not in your procedure. But I've never encountered that error, never had to check for something like this in any of MySQL.

To debug this, since it happens so rarely, I would open a case with Oracle support, and see if its possible to collect a trace/dump whenever exception ORA-1006 is raised. (I've never done a SET EVENT for that one before; I don't even know if that's possible or supported, that may be a "client side" exception, but in a PL/SQL block executing on the server, I would think it would be available. But I would do this, especially on a production database server, under the guidance of Oracle support.)

Q:

How sure are you that it's the bind_variable call in the procedure that is throwing the exception. Is that ORA-1006 exception wrapped inside an ORA-06502 exception? (I would expect to be. If it's not, then it may actually be a JDBC session that is binding variables to the procedure which is raising the exception.)

I'd be tempted to create a local procedure variable for each of the input parameters to the procedure, and then assign the input parameters to the local procedure variables. I'd also be tempted to put in an EXCEPTION handler, so I could audit the issue:

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;
Sign up to request clarification or add additional context in comments.

1 Comment

Hi Spencer7593, I will add exception handler for "bind_variable_does_not_exist" and get back to you as soon as this issue occur once again. I'm sure the above failure is only in bind_variable, since if i add debug statement before this line I'm able to print even incase of failure also. Thanks for getting back.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.