Difference Ref cursor with/with out using clause

Hi everyone,
When I am using dynamic sql with USING clause ,the results are not sorted in Ascending order.
DECLARE
TYPE emp_refcursor IS REF CURSOR;
emp_rc emp_refcursor;
TYPE v_emp_id IS TABLE OF number INDEX BY PLS_INTEGER;
TYPE v_last_name IS TABLE OF varchar2(50) INDEX BY binary_integer;
V_empno v_emp_id;
v_ename v_last_name;
p_deptno number := &U_DEPTNO;
v_limit number := 10;
v_ordcolumn varchar2(20) := 'employee_id';
v_stmt varchar2(1000);
BEGIN
v_stmt :=
'select employee_id,last_name from employees
where department_id = :x order by :y ';
dbms_output.put_line(v_stmt);
OPEN emp_rc FOR v_stmt USING p_deptno,v_ordcolumn;
LOOP
FETCH emp_rc BULK COLLECT INTO v_empno,v_ename LIMIT v_limit;
EXIT WHEN v_empno.count = 0;
FOR I IN v_empno.first .. v_empno.last
LOOP
dbms_output.put_line(v_empno(i)||' '||v_ename(i));
END LOOP;
END LOOP;
END;
When I use dynamic sql with out USING cluase,results are sorted in Ascending order.
DECLARE
TYPE emp_refcursor IS REF CURSOR;
emp_rc emp_refcursor;
TYPE v_emp_id IS TABLE OF number INDEX BY PLS_INTEGER;
TYPE v_last_name IS TABLE OF varchar2(50) INDEX BY binary_integer;
V_empno v_emp_id;
v_ename v_last_name;
p_deptno number := &U_DEPTNO;
v_limit number := 10;
v_ordcolumn varchar2(20) := 'employee_id';
v_stmt varchar2(1000);
BEGIN
v_stmt :=
'select employee_id,last_name from employees
where department_id = '||p_deptno ||
' order by '||v_ordcolumn;
dbms_output.put_line(v_stmt);
OPEN emp_rc FOR v_stmt;
LOOP
FETCH emp_rc BULK COLLECT INTO v_empno,v_ename LIMIT v_limit;
EXIT WHEN v_empno.count = 0;
FOR I IN v_empno.first .. v_empno.last
LOOP
dbms_output.put_line(v_empno(i)||' '||v_ename(i));
END LOOP;
END LOOP;
END;
P.S :---- department_id (used) = 50;
Please can some one explain why this is happening like this.
Thanks
Raghu
--------------------------------------------------------------------------------

Hi sundar,
I am new to oracle and learning/trying to get the same output by using differnt methods,rather than using FOR LOOP ,I tried to use ref cursor with dynamic sql.I am in a belief that ref cursor's with dynamic sql are faster than FOR LOOP,irrespective of the size of data.Can you correct me if I am wrong.
Coming back to ur reply,how should my statement look like,when using ref cursor
with USING claus to sort data by asc/desc order.
Thanks in advance
Raghu

Similar Messages

  • Cursor difference (REF Cursor & Sys_Refcursor)

    Hi,
    Is there any difference between REF Cursor and SYS_Refcursor?
    I see some packages using sys_refcursor and some using REF Cursor.
    Package 1 (Spec):
       PROCEDURE s_demo1 (
          ret_rset   OUT      sys_refcursor
    Package 2 (Spec):
    TYPE cur_set IS REF CURSOR;
    PROCEDURE s_test1 (out_data OUT cur_set);
    PROCEDURE s_test2 (out_data OUT cur_set);I am going through this link (http://sql-plsql.blogspot.com/2007/05/oracle-plsql-ref-cursors.html) but didn't find the answer.

    DomBrooks wrote:
    John - don't get me wrong, I'm not suggesting that as soon as something like SYS_REFCURSOR comes along, everything should get rewritten. It's just I still see new packages written on 11g by, say mainly C# or java developers, which use this old style.
    But.... are you saying that you can't do this?
    CREATE OR REPLACE PACKAGE old_package AS
    TYPE pkg_cur IS REF CURSOR;
    FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor;
    END;
    CREATE OR REPLACE PACKAGE BODY old_package AS
    FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor IS
    l_cur sys_refcursor;
    BEGIN
    OPEN l_CUR FOR SELECT * FROM dual WHERE 1 = p_id;
    RETURN l_cur;
    END;
    END;
    Absolutely, I can even declare pkg_cursor as a sys_refcursor and all of the old calls will still work since sys_refcursor is just a ref cursor in disguise. What I cannot do is drop the declaration in the package spec since the outside callers rely on it, so since sys_refcusor is just a ref cursor in disguise, why use it?
    In fact, in OHOME/rdbms/admin/stdspec.sql which is the declarations for the package standard sys_refcursor is declared as:
      /* Adding a generic weak ref cursor type */
      type sys_refcursor is ref cursor;Since things declared in standard package (like data types, operators, all of the named exceptions etc.) are "globally" available without using the package name, sys_refcursor just provides a method to save a few keystrokes everywhere. It is no different functionally than a package declared ref cursor. The main difference is that you cannot create a strongly typed sys_refcursor, if you want/need one, you need to use a ref cursor.
    I do tend to use sys_refcursor in new code, but it took me a while to switch because there is not much real benefit as far as I can see.
    John
    Edited by: John Spencer on Nov 17, 2010 4:11 PM

  • Returning a Ref cursor as an OUT Parameter

    Hi Guys
    I have defined 2 Types and 2 Ref cursors as shown below.I have written a procedure having 2 IN and 2 OUT parameters which are of type Ref cursors and return records to the calling client. My question is how can i test for the output of the two cursors here in pl/sql?.. also i should not close the sursors.. right?..its the job of the calling client as per my knowledge....Please suggest
    TYPE type_dept_Rec IS RECORD(deptNo varchar2);
    TYPE type_prod_Rec IS RECORD(prodType varchar2);
    TYPE deptCursor IS REF CURSOR RETURN type_dept_Rec;
    TYPE prodCursor IS REF CURSOR RETURN type_prod_Rec;
    PROCEDURE TEST (pinCode IN varchar2, prodType IN number, deptCursor OUT deptType, productCursor OUT deptType) IS
    BEGIN
    OPEN deptCursor FOR SELECT
    deptNo
    from
    DEPT
    where
    pinCode = pinCode;
    OPEN productCursor FOR SELECT
    prodCode
    from
    PROD
    where
    prodType = prodType;
    end;

    A Correction to the above code snippet
    Hi Guys
    I have defined 2 Types and 2 Ref cursors as shown below.I have written a procedure having 2 IN and 2 OUT parameters which are of type Ref cursors and return records to the calling client. My question is how can i test for the output of the two cursors here in pl/sql?.. also i should not close the sursors.. right?..its the job of the calling client as per my knowledge....Please suggest
    TYPE type_dept_Rec IS RECORD(deptNo varchar2);
    TYPE type_prod_Rec IS RECORD(prodType varchar2);
    TYPE deptCursor IS REF CURSOR RETURN type_dept_Rec;
    TYPE prodCursor IS REF CURSOR RETURN type_prod_Rec;
    PROCEDURE TEST (pinCode IN varchar2, prodType IN number, deptCursor OUT deptCursor, productCursor OUT prodCursor) IS
    BEGIN
    OPEN deptCursor FOR SELECT
    deptNo
    from
    DEPT
    where
    pinCode = pinCode;
    OPEN productCursor FOR SELECT
    prodCode
    from
    PROD
    where
    prodType = prodType;
    end

  • Performance problem with sproc and out parameter ref cursor

    Hi
    I have sproc with Ref Cursor as an OUT parameter.
    It is extremely slow looping over the ResultSet (does it record by record in the fetch).
    so I have added setPrefetchRowCount(100) and setPrefetchMemorySize(6000)
    pseudo code below:
    string sqlSmt = "BEGIN get_tick_data( :v1 , :v2); END;";
    Statement* s = connection->createStatement(sqlStmt);
    s->setString(1, i1);
    // cursor ( f1 , f2, f3 , f4 , i1 ) f for float type and i for interger value.
    // 5 columns as part of cursor with 4 columns are having float value and
    // 1 column is having int value assuming 40 bytes for one rec.
    s->setPrefetchRowCount (100);
    s->PrefetchMemorySize(6000);
    s->registerOutParam(2,OCCICURSOR);
    s->execute();
    ResultSet* rs = s->getCursor(2);
    while (rs->next()) {
    // do, and do v slowly!
    }

    Hi,
    I have the same problem. It seems, when retrieving cursor, that "setPrefetchRowCount" is not taking into account by OCCI. If you have a SQL statement like "SELECT STR1, STR2, STR3 FROM TABLE1" that works fine but if your SQL statement is a call to a stored procedure returning a cursor each row fetching need a roudtrip.
    To avoid this problem you need to use the method "setDataBuffer" from the object "ResultSet" for each column of your cursor. It's easy to use with INT type and STRING type, a lit bit more complex with DATE type. But until now, I'm not able to do the same thing with REF type.
    Below a sample with STRING TYPE (It's assuming that the cursor return only one column of STRING type):
    try
      l_Statement = m_Connection->createStatement("BEGIN :1 := PACKAGE1.GetCursor1(:2); END;");
      l_Statement->registerOutParam(1, oracle::occi::OCCINUMBER, sizeof(l_CodeErreur));
      l_Statement->registerOutParam(2, oracle::occi::OCCICURSOR);
      l_Statement->executeQuery();
      l_CodeErreur = l_Statement->getNumber(1);
      if ((int) l_CodeErreur     == 0)
        char                         l_ArrayName[5][256];
        ub2                          l_ArrayNameSize[5];
        l_ResultSet  = l_Statement->getCursor(2);
        l_ResultSet->setDataBuffer(1, l_ArrayName,   OCCI_SQLT_STR, sizeof(l_ArrayName[0]),   l_ArrayNameSize,   NULL, NULL);
        while (l_ResultSet->next(5))
          for (int i = 0; i < l_ResultSet->getNumArrayRows(); i++)
            l_Name = CString(l_ArrayName);
    l_Statement->closeResultSet(l_ResultSet);
    m_Connection->terminateStatement(l_Statement);
    catch (SQLException &p_SQLException)
    I hope that sample help you.
    Regards                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • REF cursor with special characters

    Hi all,
    I want to display the record set using ref cursor. I am passing varchar field as parameter. How to give this in where cluase of select statement.
    i want to use like %parameter_name% in where condition. How to use it in ref cursor.
    Thanks in advance,
    Pal

    user546710 wrote:
    Hi all,
    I want to display the record set using ref cursor. I am passing varchar field as parameter. How to give this in where cluase of select statement.
    i want to use like %parameter_name% in where condition. How to use it in ref cursor.
    Thanks in advance,
    PalWhy using a ref cursor? Do you understand the purpose of ref cursors and how to use them?
    Perhaps take a read of the following to get to grips with the basics...
    PL/SQL 101 : Understanding Ref Cursors
    PL/SQL 101 : Understanding Ref Cursors

  • Ora-01001 in procedures with ref cursor parameter after upgrade to 11.1.0.7

    Hi,
    after upgrading from 11.1.0.6.0 to 11.1.0.7.0, I get ora-01001 in procedure calls which have a ref cursor as an out parameter.
    Even a new 11.1.0.7 instance throws this error. My OS is Linux SLES10SP2.
    Please see atched sample code:
    CREATE OR REPLACE PACKAGE test1_pck
    IS
    PROCEDURE run1; -- OK on 11.1.0.6; fails on 11.1.0.7
    PROCEDURE run2; -- OK on 11.1.0.6; OK on 11.1.0.7
    END test1_pck;
    CREATE OR REPLACE PACKAGE BODY test1_pck
    IS
    TYPE t_rec IS RECORD(col dual.dummy%TYPE);
    TYPE t_cur IS REF CURSOR RETURN t_rec;
    PROCEDURE foo1(p_cur OUT t_cur)
    IS
    v_sql VARCHAR2(255) := 'BEGIN OPEN :1 FOR SELECT dummy FROM dual; END;';
    BEGIN
    EXECUTE IMMEDIATE v_sql USING p_cur;
    END foo1;
    PROCEDURE foo2
    IS
    v_sql VARCHAR2(255) := 'BEGIN OPEN :1 FOR SELECT dummy FROM dual; END;';
    v_cur t_cur;
    v_rec t_rec;
    BEGIN
    EXECUTE IMMEDIATE v_sql USING v_cur;
    LOOP
    FETCH v_cur INTO v_rec;
    EXIT WHEN v_cur%NOTFOUND;
    CASE v_rec.col
    WHEN 'X' THEN dbms_output.put_line('success');
    ELSE dbms_output.put_line('error');
    END CASE;
    END LOOP;
    END foo2;
    PROCEDURE run1
    IS
    v_cur t_cur;
    v_rec t_rec;
    BEGIN
    foo1(v_cur);
    LOOP
    FETCH v_cur INTO v_rec;
    EXIT WHEN v_cur%NOTFOUND;
    CASE v_rec.col
    WHEN 'X' THEN dbms_output.put_line('success');
    ELSE dbms_output.put_line('error');
    END CASE;
    END LOOP;
    END run1;
    PROCEDURE run2
    IS
    BEGIN
    foo2;
    END run2;
    END test1_pck;
    Thanks for any hints.
    Regards Frank

    Hi Max,
    the referenced thread discusses a .Net problem. A lot of layers are involved their. My problem is a very basic problem. You get this error even if you run the test in a sql session on the server.
    It would be a great help for me
    a) if someone could test this package on a 11.1.0.7 database
    b) if someone could test this package on a 11.2 database (is it fixed in Release2?)
    c) if someone could give me hints how I could modify the procedure to make it usable for 11.1.0.7
    (I already tried a lot e.g. EXECUTE IMMEDIATE v_sql USING OUT p_cur;
    Thank you
    Frank

  • Executing procedure with IN OUT parameters using SQL developer

    Hi, I'm trying to exceute the below procedure in SQL developer. Here the IN OUT cursor 'journal_cursor' is already defined.
    PROCEDURE LIST_FORPROJECT (
              p_project_sid IN NUMBER,
              p_journal_cursor IN OUT journal_cursor,
         AS
         BEGIN
              OPEN p_journal_cursor FOR
              -- get the journal
                   SELECT j.JOURNAL_KEY AS "Journal_SID",
                             j.JOURNALTEXT AS "Entry",
                             j.CREATEDATE AS "CreateDate",
                             --j.COMMENT_ AS "Comment",
                             j.PROJECTPHASETASK_KEY AS "ProjectPhaseTaskSet_SID",
                             j.person_key AS "Person_SID"
    FROM vdl_JOURNAL j
                   INNER JOIN vdl_PROJECTJOURNAL pj ON pj.JOURNAL_KEY = j.JOURNAL_KEY
                   WHERE pj.PROJECT_KEY = p_project_sid
                   ORDER BY j.CREATEDATE ASC, j.JOURNAL_KEY ASC;
    END LIST_FORPROJECT;
    When trying to run the above procedure through SQL developer, I get the below code generated.
    DECLARE
    P_PROJECT_SID NUMBER;
    P_JOURNAL_CURSOR journal_cursor;
    BEGIN
    P_PROJECT_SID := 5974;
    -- Modify the code to initialize the variable
    -- P_JOURNAL_CURSOR := NULL;
    -- Modify the code to initialize the variable
    LIST_FORPROJECT(
    P_PROJECT_SID => P_PROJECT_SID,
    P_JOURNAL_CURSOR => P_JOURNAL_CURSOR,
    -- Modify the code to output the variable
    DBMS_OUTPUT.PUT_LINE('P_JOURNAL_CURSOR' || P_JOURNAL_CURSOR);
    END;
    But executing the above sql doesn't print the cursor as output but errors out saying 'wrong number or type or arguments in call to ||'. Can somebody please help me in finding a way test and view the results of such a procedure through SQL developer?
    Any help is highly appreciated.
    Regards,
    Ranganath

    Hi,
    I was able to solve the problem.. My cursor was declared like this.
    TYPE journal_def IS RECORD
              journal_sid                    NUMBER(10),
              journaltext                    CLOB,
              createdate                    DATE,
              projectphasetaskset_sid     NUMBER(10),
              person_sid                    NUMBER(10)
    TYPE journal_cursor                    IS REF CURSOR RETURN journal_def;
    I used the journal_def type to fetch the records.
    Here is how my final sql looked like.
    DECLARE
    P_PROJECT_SID NUMBER;
    P_JOURNAL_CURSOR journal_cursor;
    P_J_CURSOR journal_def;
    BEGIN
    P_PROJECT_SID := 11171;
    -- Modify the code to initialize the variable
    -- P_JOURNAL_CURSOR := NULL;
    LIST_FORPROJECT(
    P_PROJECT_SID => P_PROJECT_SID,
    P_JOURNAL_CURSOR => P_JOURNAL_CURSOR,
    -- Modify the code to output the variable
    BEGIN
    --open P_JOURNAL_CURSOR;
    loop
    fetch P_JOURNAL_CURSOR into P_J_CURSOR;
    exit when P_JOURNAL_CURSOR%NOTFOUND;
    DBMS_OUTPUT.put_line(P_J_CURSOR.journal_sid);
    end loop;
    --close P_JOURNAL_CURSOR;
    END;
    END;
    This gave me results. Thanks a ton ALL for your help..... :)..
    Regards,
    Ranganath

  • Need Help: Using Ref Cursor in ProC to call a function within a Package

    I'm calling a function within a package that is returning a REF CURSOR.
    As per the Oracle Pro*C Programmer's Guide, I did the following:
    1) declared my cursor with a: EXEC SQL BEGIN DECLARE SECTION and declared the cursor as: SQL_CURSOR my_cursor;
    2) I allocated the cursor as: EXEC SQL ALLOCATE :my_cursor;
    3) Via a EXEC SQL.....END-EXEC begin block
    I called the package function and assign the return value to my cursor
    e.g. my_cursor := package.function(:host1, :host2);
    Now, the only difference between my code and the example given in the Pro*C Programmer's Guide is that the example calls a PROCEDURE within a package that passes back the REF CURSOR as an OUT host variable.
    Whereas, since I am calling a function, the function ASSIGNS the return REF CURSOR in the return value.
    If I say my_cursor := package.function(:host1, :host2); I get a message stating, "PLS-00201: identifier MY_CURSOR" must be declared"
    If I say :my_cursor := package.function(:host1, :host2); I get a message stating, "ORA-01480: trailing null missing from STR bind value"
    I just want to call a package function and assign the return value to a REF CURSOR variable. There must be a way of doing this. I can do this easily in standard PL/SQL. How can this be done in Pro*C ???
    Thanks for any help.

    Folks, I figured it out. For those who may face this problem in the future you may want to take note for future reference.
    Oracle does not allow you to assign the return value of a REF CURSOR from a FUNCTION ( not Procedure - - there is a difference) directly to a host variable. This is the case even if that host variable is declared a CURSOR variable.
    The trick is as follows: Declare the REF CURSOR within the PL/SQL BEGIN Block, using the TYPE statement, that will contain the call to the package function. On the call, you then assign the return REF CURSOR value that the function is returning to your REF CURSOR variable declared in the DECLARE section of the EXEC SQL .... END-EXEC PL/SQL Block.
    THEN, assign the REF CURSOR variable that was populated from the function call to your HOST cursor varaible. Then fetch this HOST Cursor variable into your Host record structure variable. Then you can deference individual fields as need be within your C or C++ code.
    I hope this will help someone facing a deadline crunch. Happy computing !

  • Using a strongly typed ref cursor doesn't enforce data type

    I am trying to enforce the datatypes of the fields coming back from an oracle reference cursor by making it strongly typed. However, there seems to be no warning at compile time on the oracle side or exception in ODP.NET if the datatype coming back in the cursor does not match. For example here is my cursor and proc
    create or replace
    PACKAGE THIRDPARTY AS
    type pricing_record is record
    BaseIndexRate     number(6,5),
    BaseIndexRateType     VARCHAR2(1 BYTE)
    type cur_pricing2 IS ref CURSOR return pricing_record;
    PROCEDURE getpricingbyappidtest(appid IN application.intid%TYPE, pricing OUT cur_pricing2);
    END THIRDPARTY;
    create or replace
    PACKAGE BODY THIRDPARTY AS
    PROCEDURE getpricingbyappidtest(appid IN application.appid%TYPE, pricing OUT cur_pricing2)
    AS
    BEGIN
         OPEN pricing FOR
         SELECT      somevarcharfield, someothervarcharfield
    FROM application
    WHERE A.appid = appid;
    END getpricingbyappidtest;
    I would expect this wouldn't compile since i am putting a varchar into a number field. But it does. Also if i check the datatype in the reader on the .net side it also is a string. So odp doesn't seem to care what type the cursor is
    here is that code and output
    var schemaTable = reader.GetSchemaTable();
    using (var file = new System.IO.StreamWriter("c:\\_DefinitionMap_" + cursorName + ".txt"))
    file.WriteLine("COLUMN" + "\t" + "DATATYPE");
    foreach (DataRow myField in schemaTable.Rows)
    file.WriteLine(myField["ColumnName"] + "\t" + myField["DataType"]);
    COLUMN     DATATYPE
    BaseIndexRate     System.String
    BaseIndexRateType     System.String
    Does anyone have an approach for enforcing datatypes in a ref cursor? Am I doing something wrong when defining the ref cursor?

    Hello,
    By using a ref cursor you are really using a pointer to a cursor. There is no way I know of to make a compile check of the cursor check unless you want to create a SQL type and cast the cursor to this type and even this wouldn't work in all cases. For instance, I could have function call within my cursor select which could return a varchar (with a number always in the varchar) which would be horribly sloppy but legal and you would expect Oracle to compile it.
    If you are worried about this I would suggest not using ref cursors and go to UDT instead, where there will be more checking (because of a C# equivalence generated object). Oh and BTW, yes the cursor will throw an exception if the data is incorrect, but only at runtime - just like normal Oracle PLSQL.
    Cheers
    Rob.
    http://www.scnet.com.au

  • Help needed in Ref cursor

    Hi,
    I am new to Ref Cursor concepts and I am trying a small block but its throwing error. Pls help me.
    PACKAGE SPEC:
    CREATE OR REPLACE PACKAGE PKG_JOBINFO AS
    PROCEDURE JOBINFO ( v_job_id IN number, p_cursor OUT PKG_JOBINFO.RESULT_REF_CURSOR);
    TYPE RESULT_REF_CURSOR IS REF CURSOR;
    END PKG_JOBINFO;
    PACKAGE BODY:
    CREATE OR REPLACE package body PKG_JOBINFO
    AS
    PROCEDURE JOBINFO ( v_job_id IN number,
    p_cursor OUT PKG_JOBINFO.RESULT_REF_CURSOR)
    AS
    BEGIN
    OPEN p_cursor FOR
    SELECT JOB_ID,
    JOB_NAME,
    TABLE_NAME
    FROM JOB_INFO
    WHERE JOB_ID=V_JOB_ID;
    EXCEPTION
    WHEN OTHERS THEN
    raise;
    END;
    END;
    While compiling the package i am not getting any errors. I am getting errors only while executing
    SQL> exec PKG_JOBINFO.JOBINFO ('23');
    BEGIN PKG_JOBINFO.JOBINFO ('23'); END;
    ERROR at line 1:
    ORA-06550: line 1, column 7:
    PLS-00306: wrong number or types of arguments in call to 'JOBINFO'
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored
    Please help me to resolve this error.
    Thanks.

    user497267 wrote:
    Thanks its working. So if we are using ref cursor we have to execute like this only.To add...
    The actual issue you were experiencing was not because you were using ref cursors specifically, but because you had an OUT parameter in your procedure.
    When you have an OUT parameter, you need to ensure that you pass in a variable to that parameter of the procedure in order that the procedure can populate it. In your case you were only passing in the first parameter, but you weren't passing in a variable to capture the OUTput.
    What Alex showed was that by declaring a variable of the same datatype (ref cursor in your case) and passing that in as the second parameter, that variable was populated with the ref cursor information from inside the procedure. Once that variable was populated, after the procedure call, the data from that ref cursor can be obtained (using SQL*Plus' print command in Alex's example).

  • Re: PLS-00455: cursor 'CUR_1' cannot be used in dynamic SQL OPEN statement

    create or replace package cognos_pk as /* Creates Package Header*/
    TYPE project_type IS record( /* A record declaration is used to */
    c1 NUMBER /* provide a definition of a record */
    ); /* that can be used by other variables*/
    TYPE project_type1 IS REF CURSOR  return project_type; /* Variable declaration */
    procedure conosg_sp (result1  out project_type1); /* SP declaration */
    end;
    CREATE OR REPLACE PACKAGE BODY cognos_pk AS /* Name of package body must be same as header */
    PROCEDURE conosg_sp(result1  OUT project_type1) IS
    countrow  number;
    BEGIN
    FOR X IN (SELECT TABLE_NAME
    FROM USER_TAB_COLUMNS
    WHERE COLUMN_NAME='PROC_STAT_CODE' AND TABLE_NAME LIKE 'INPT%')
    LOOP
    execute immediate 'select count(*)   from '||X.TABLE_NAME ||' WHERE PROC_STAT_CODE &lt;&gt;10 ' into countrow;
    --result1 := X.TABLE_NAME|| ROW_CNT;
    -- dbms_output.put_line(result1 );
    OPEN result1 for countrow;
    END loop;
    END;
    end;
    /This is my requirement ...
    I want to count the table starting with Inpt and and proc stat _code =10 which is the column name in all the table.
    i wan to return the count and the table name to be used in my cognos report.
    Edited by: BluShadow on 10-May-2013 09:22
    added {noformat}{noformat} tags around the code/data for readability (no accounting for OP's lack of formatting)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    1005181 wrote:
    create or replace package cognos_pk as /* Creates Package Header*/
    TYPE project_type IS record( /* A record declaration is used to */
    c1 NUMBER /* provide a definition of a record */
    ); /* that can be used by other variables*/
    TYPE project_type1 IS REF CURSOR  return project_type; /* Variable declaration */
    procedure conosg_sp (result1  out project_type1); /* SP declaration */
    end;
    CREATE OR REPLACE PACKAGE BODY cognos_pk AS /* Name of package body must be same as header */
    PROCEDURE conosg_sp(result1  OUT project_type1) IS
    countrow  number;
    BEGIN
    FOR X IN (SELECT TABLE_NAME
    FROM USER_TAB_COLUMNS
    WHERE COLUMN_NAME='PROC_STAT_CODE' AND TABLE_NAME LIKE 'INPT%')
    LOOP
    execute immediate 'select count(*)   from '||X.TABLE_NAME ||' WHERE PROC_STAT_CODE &lt;&gt;10 ' into countrow;
    --result1 := X.TABLE_NAME|| ROW_CNT;
    -- dbms_output.put_line(result1 );
    OPEN result1 for countrow;
    END loop;
    END;
    end;
    /This is my requirement ...
    I want to count the table starting with Inpt and and proc stat _code =10 which is the column name in all the table.
    i wan to return the count and the table name to be used in my cognos report.The execute immediate statement you have, is doing the actual count and returning the count into the variable "countrow".
    The subsequent OPEN statement for the ref cursor is trying to open a cursor, and is expecting an SQL query to do that, but you are passing it your numeric value instead.
    All you need to open a ref cursor is:
    e.g.
    OPEN result1 for 'select count(*) from '||x.table_name||' where proc_stat_code != 10';However, your code is so seriously flawed in many ways.
    a) you don't need to declare a type of "REF CURSOR" yourself. Oracle provides a type called "SYS_REFCURSOR" that you can use already.
    b) Your procedure is supplying a single ref cursor as an OUT variable, yet it tries to loop through multiple tables and re-use the same ref cursor over and over. That's not going to work. You can only pass one thing out in your OUT parameter.
    I don't know how congos expects it's results, but I assume a ref cursor is acceptable to it, so what you're actually looking for is to pass back a single ref cursor that is based on a query that can give the results for all your tables in one go.
    There are various queries that can be used to count records on multiple tables e.g.
    (ref. Laurent Schneider's blog: http://laurentschneider.com/wordpress/2007/04/how-do-i-store-the-counts-of-all-tables.html )
    SQL> select
      2    table_name,
      3    to_number(
      4      extractvalue(
      5        xmltype(
      6 dbms_xmlgen.getxml('select count(*) c from '||table_name))
      7        ,'/ROWSET/ROW/C')) count
      8  from user_tables
      9 where iot_type != 'IOT_OVERFLOW'
    10 or    iot_type is null;
    TABLE_NAME                      COUNT
    DEPT                                4
    EMP                                14
    BONUS                               0
    SALGRADE                            5You could therefore open your refcursor using a single query based on the above (adapting it for your own needs and restrictions).

  • Ref cursor trouble

    Hi All,
    My requirement is to fetch values from any given tables through ref cursor, so i have used a below procedure
    CREATE OR REPLACE
    PROCEDURE et1(
        tab_name IN VARCHAR2,
        c1 OUT sys_refcursor)
    AS
      v_prim_val VARCHAR2(2000);
      v_sql      VARCHAR2(2000);
    BEGIN
      SELECT wm_concat(s.column_name)
      INTO v_prim_val
      FROM user_cons_columns s ,
        user_constraints c
      WHERE c.constraint_name=s.constraint_name
      AND c.constraint_type  ='P'
      AND s.table_name       =tab_name;
      dbms_output.put_line('Col val='||v_prim_val);
      v_sql:='select '||v_prim_val|| ' from easy where id in (1,2,3)';
      OPEN c1 FOR v_sql;
    END et1;
    /Problem with above code is the record set returned by ref cursor will be unknown so in which variable should i put it in?
    below code will create table for above procedure
    create table easy(id integer, event_rowid integer,txn_rowid integer,txn_name varchar2(200));
    begin
    for i in 1..5 loop
    insert into easy values(i,'777'||i,i||89,'Ris'||i||i);
    end loop;
    end;
    commit;
    alter table easy add constraint pk_easy primary key(id,event_rowid,txn_name);While googling i found "we can't fetch into a variable of the weak cursor's row type." But I don't know the record set or the variables being returned .
    Please help!

    983088 wrote:
    Is there alternative for wm_concat?Read the FAQ: {message:id=9360005}
    under the string aggregation techniques
    Thanks Billy for your reply
    I had a requirement and i tried something , apparently it's a fiasco
    I understand static sql is the key but not for my Lock.
    I have 300 tables in my Database ,I have to fetch primary key and there values on some condition which user will pass .So, you're saying a user should be able to extract any data they want from any table of their choice with any conditions they want? Such 'users' are usually technical administrators who know the database and are trusted not to damage things.
    Now please tell me when i don't know which table they will pass and table may have any number of primary keys and if i have used dynamic sql so what's wrong in that?It means that your business requirement is too 'generic' and there is no solid design to what the requirements are.
    what approach should i follow?Use the DBMS_SQL package. This allows a 'dynamic' query to be constructed, parsed (and thus validated) and then queried where you can fetch the columns by numeric position (column number 1, column number 2 etc.) as well as determining their datatypes and names etc.
    An example from my standard library of examples, where I use DBMS_SQL to take any query and extract the details of that query to output the data returned as a CSV file...
    As sys user:
    CREATE OR REPLACE DIRECTORY TEST_DIR AS '\tmp\myfiles'
    GRANT READ, WRITE ON DIRECTORY TEST_DIR TO myuser
    /As myuser:
    CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
                                         ,p_dir IN VARCHAR2
                                         ,p_header_file IN VARCHAR2
                                         ,p_data_file IN VARCHAR2 := NULL) IS
      v_finaltxt  VARCHAR2(4000);
      v_v_val     VARCHAR2(4000);
      v_n_val     NUMBER;
      v_d_val     DATE;
      v_ret       NUMBER;
      c           NUMBER;
      d           NUMBER;
      col_cnt     INTEGER;
      f           BOOLEAN;
      rec_tab     DBMS_SQL.DESC_TAB;
      col_num     NUMBER;
      v_fh        UTL_FILE.FILE_TYPE;
      v_samefile  BOOLEAN := (NVL(p_data_file,p_header_file) = p_header_file);
    BEGIN
      c := DBMS_SQL.OPEN_CURSOR;
      DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
      d := DBMS_SQL.EXECUTE(c);
      DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
      FOR j in 1..col_cnt
      LOOP
        CASE rec_tab(j).col_type
          WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
          WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
          WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
        ELSE
          DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
        END CASE;
      END LOOP;
      -- This part outputs the HEADER
      v_fh := UTL_FILE.FOPEN(upper(p_dir),p_header_file,'w',32767);
      FOR j in 1..col_cnt
      LOOP
        v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
      END LOOP;
      --  DBMS_OUTPUT.PUT_LINE(v_finaltxt);
      UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
      IF NOT v_samefile THEN
        UTL_FILE.FCLOSE(v_fh);
      END IF;
      -- This part outputs the DATA
      IF NOT v_samefile THEN
        v_fh := UTL_FILE.FOPEN(upper(p_dir),p_data_file,'w',32767);
      END IF;
      LOOP
        v_ret := DBMS_SQL.FETCH_ROWS(c);
        EXIT WHEN v_ret = 0;
        v_finaltxt := NULL;
        FOR j in 1..col_cnt
        LOOP
          CASE rec_tab(j).col_type
            WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
                        v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
            WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
                        v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
            WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
                        v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
          ELSE
            DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
            v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
          END CASE;
        END LOOP;
      --  DBMS_OUTPUT.PUT_LINE(v_finaltxt);
        UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
      END LOOP;
      UTL_FILE.FCLOSE(v_fh);
      DBMS_SQL.CLOSE_CURSOR(c);
    END;This allows for the header row and the data to be written to seperate files if required.
    e.g.
    SQL> exec run_query('select * from emp','TEST_DIR','output.txt');
    PL/SQL procedure successfully completed.Output.txt file contains:
    empno,ename,job,mgr,hiredate,sal,comm,deptno
    7369,"SMITH","CLERK",7902,17/12/1980 00:00:00,800,,20
    7499,"ALLEN","SALESMAN",7698,20/02/1981 00:00:00,1600,300,30
    7521,"WARD","SALESMAN",7698,22/02/1981 00:00:00,1250,500,30
    7566,"JONES","MANAGER",7839,02/04/1981 00:00:00,2975,,20
    7654,"MARTIN","SALESMAN",7698,28/09/1981 00:00:00,1250,1400,30
    7698,"BLAKE","MANAGER",7839,01/05/1981 00:00:00,2850,,30
    7782,"CLARK","MANAGER",7839,09/06/1981 00:00:00,2450,,10
    7788,"SCOTT","ANALYST",7566,19/04/1987 00:00:00,3000,,20
    7839,"KING","PRESIDENT",,17/11/1981 00:00:00,5000,,10
    7844,"TURNER","SALESMAN",7698,08/09/1981 00:00:00,1500,0,30
    7876,"ADAMS","CLERK",7788,23/05/1987 00:00:00,1100,,20
    7900,"JAMES","CLERK",7698,03/12/1981 00:00:00,950,,30
    7902,"FORD","ANALYST",7566,03/12/1981 00:00:00,3000,,20
    7934,"MILLER","CLERK",7782,23/01/1982 00:00:00,1300,,10-----
    Billy ,BTW u made my day i was just telling my girlfriend i got a reply from Oracle Ace, THXSmall things please ....

  • [b]HELP-Accessing REF CURSOR (select *   from *) from OCI[/b]

    I have a stored procedure that returns a weak REF CURSOR as an out parameter. I want to access the rows that are returned, in an OCI application. I want a sample OCI program that does this. The PL/SQL code is as follows
    PACKAGE TEST_PACKAGE AS
    TYPE RCT IS REF CURSOR;
    END;
    PROCEDURE TEST_PROCEDURE (R OUT TEST_PACKAGE.RCT)
    AS
    BEGIN
    OPEN r FOR
    SELECT * FROM XXX;
    END;
    THANKS.

    Hello,
    I used in my application regular connections, I created
    CallableStatement with these connections, later I got one cursor with:
    mr = ((OracleCallableStatement)cstmt).getCursor(1)
    where mr is ResultSet and cstmt is CallableStatement.
    But, when I use the Commerce PoolConnection I get serialConnection
    and it creates serialCallableStatement and the command:
    mr = ((OracleCallableStatement)cstmt).getCursor(1)
    get the next exception:
    java.lang.ClassCastException:
    weblogic.jdbc20.rmi.SerialCallableStatement at......
    Are you working with Bea ConnectionPool
    or regular Connections?
    Thank you.
    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Matt Sivertson ([email protected]):
    I'm having a very strange problem with some JDBC code. Basically, there is a StoredProcedure in the DB that we call through JDBC. One of the out parameters is a REF CURSOR. My user does not have select access to the table, but the stored procedure does. When I try and get the ResultSet corresponding to that RefCursor using the OracleCallableStatement.getCursor() method, and exception gets thrown saying it cannot find the table. We checked on the database, and it is actually performing a new select statement as My user, rather than as the StoredProcedure. If we open up the permissions on the table, everything works fine, but this defeats the whole purpose of what the DBA wants.
    BTW, this same Stored Procedure works when fine when accesed through PL/SQL or SQL+. Only JDBC seems to have a problem with it. Any help is greatly appreciated.
    Matt Sivertson
    [email protected]<HR></BLOCKQUOTE>
    null

  • Cast error message when discovering ref cursor parameter from stored proced

    We are today using Microsoft's Oracle provider with some code from the old Data Application Block (from MSDN) to discover parameters from the stored procedures. This code uses the OracleCommandBuilder.DeriveParameters to get the parameters from the stored procedure and command.Parameters.CopyTo copies the discovered parameters into the command object.
    If I test with a simple function returning a ref cursor I get one parameter with type refCursor and ParameterDirection.OutPut. This is working fine as long we where using Microsoft's Oracle provider. But using Oracle ODP .NET I get the following error message on datadapter.Fill (I fill a dataset with the result from the reference cursor)
    Unable to cast object of Type 'Oracle.DataAccess.Client.OracleDataReader' to type 'Oracle.DataAccess.Types.OracleRefCursor.
    If I create a ref parameter manualy like this:
    OracleParameter myrefCursor = new OracleParameter();
    myrefCursor .OracleDbType = OracleDbType.RefCursor;
    myrefCursor .ParameterName = "myParameterName";
    myrefCursor .Direction = ParameterDirection.ReturnValue;
    and add it to the command object this is working OK. So it seems to be a problem with discovering ref cursor parameters from the database, other parameter types is OK.. I have compared the properties of my manual ref cursor parameter with the one discovered from the stored procedure, but I cannot see any difference. (I see the Value property has some values for the discovered one, but I have set this to DBNull.Value without any result)
    Any ideas why I get this error code? Is there any other code blocks I can use to discover the parameters? We send in params object[] with the different values into the helper class and the value is added to the parameter. (Se I don't need to set the data type etc for each parameter, I just need to have the correct order of the parameters)

    For accuracy's sake, just wanted to let everyone know that this is actually a bug. The correct bug number is 8423178.
    Christian
    Mark_Williams wrote:
    Just to follow-up on this issue...
    The bug has been closed as "not a bug" as it seems undocumented behavior was relied upon for this to work in earlier releases.
    Note from the documentation on DeriveParameters:
    "The output values of derived parameters return as .NET Types by default. To obtain output parameters as provider types, the OracleDbType property of the parameter must be set explicitly by the application to override this default behavior. One quick way to do this is to set the OracleDbType to itself for all output parameters that should be returned as provider types." (emphasis added)
    The issue, as you might already know, is that there is no corresponding .NET Framework Type for an Oracle Ref Cursor and the type is, therefore, set to Object. So, explicitly setting the type to OracleDbType.RefCursor should work.
    Regards,
    Mark

  • Joining a ref cursor to a table

    Dear all;
    Can you please show me a simple example on how to join a ref cursor to a table because I have a function that returns a ref cursor and I would like to call that function in another function(function B) and then join it to a table in that function(function B)

    user13328581 wrote:
    well, I personnally know it is a bad idea but my fellow senior keeps advicing me to do it. Their reason is based on the code reusability aspect of things. I had a function 1 already created which returned a ref cursor and basically within that function is a complex select statement. Now I have function 2 which is making use of a similar select statement, the only different between the two select statment is based on the fact, the function 2 select statement is joining to another table at the very end, so based on their argument they want me to call that select statement from function 1 and join it to that table instead...Then your "+seniors+" need to extract their heads from whatever dark orifice they have it stuck in, as this is not how '"+code reusability+" works in the Oracle environment.
    In the SQL language, views are used to create re-usable SQL source code.
    In Oracle, the Shared Pool is used to create and store cursors for reuse (assuming the SQL source allows reusability and uses bind variables).
    Joining a ref cursor (code) with a table (data) is just plain stupid - and no amount of "code reusability" arguing will change this fact.

Maybe you are looking for