WEAK REF CURSOR type

This is the first time I have a need at work to use a REF CURSOR type of the weak variety. After reading documentation
in SF's 'bible' Oracle PL/SQL Programming, I did everything right. Here's the code snippet:
-- TYPES
TYPE content_ID_curtype IS
REF CURSOR;
-- VARIABLES
c_SEARCH_STRING CONSTANT VARCHAR2(12) := 'v_content_id';
content_ID_cur content_ID_curtype;
v_content_ID am_content_content.content_ID%TYPE;
BEGIN
cache_sql_rec.sql_stmt := REPLACE(cache_sql_rec.sql_stmt, c_SEARCH_STRING, template_name_rec.content_ID);
OPEN content_ID_cur FOR cache_sql_rec.sql_stmt;
LOOP
FETCH content_ID_cur
INTO v_content_ID;
EXIT WHEN content_ID_cur%NOTFOUND;
END LOOP;
CLOSE content_ID_cur;
END;
Now the error I get is.... ORA-00911: invalid character When I used DBMS_OUTPUT to see the actual value of
"cache_sql_rec.sql_stmt", the SQL query looks fine. Even when I hardcoded the sql statement after the FOR keyword, it
worked fine. It's only when I use a variable to hold the whole SQL statement does it fail. Here's one value for the
variable cache_sql_rec.sql_stmt:
SELECT b.content_id
FROM am_content_mofcollection a,
am_content_collection b
WHERE a.content_id = 149090
AND a.collection_id = b.collection_id;
Basically I replace the string with an actual content_ID. Now content_ID is of type NUMBER(12) as is the variable
v_content_ID declared so that I FETCH INTO that variable, but the problem is, is that the exception gets raised during
the OPEN...cursor...FOR....sql_statement command.
Any thoughts on this bug?
Thanks,
Gio
Giovanni Jaramillo
Senior Software Engineer
Oracle Database Group
Amplified Holdings, Inc.
5750 Wilshire Blvd., Ste 501
Los Angeles, CA 90036-3638
(323)-556-8792
[email protected] http://www.amplified.com

Yes it turns out that the data had a semicolon at the end since it's being inserted by someone else. I know when executing DDL or DML statements via NDS you omit the semicolon. But didn't know it applied to REF CURSORS.
Also I added a colon to the variable that I was REPLACING since it can act as a bind variable.
Thanks Andrew.
Gio
null

Similar Messages

  • Describe weak ref cursor

    I want to implement a stored procedure which takes a
    weak ref cursor as one of its IN parameters. In the body
    of the SP I want to analyze the "structure" of the weak
    ref cursor: column names and types.
    Any hints how to do this in PL/SQL?? Of course, in C via OCI
    describing a (weak) ref cursor at run-time is no problem at
    all.
    Tobias.

    it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
    There is one way.....you can discard the first n records while assigning the query to cursor variable....
    Frame ur query that ur going to assocaite to the cursor in the following way....
    select * from (select rownum a, test.* from test) where a > N
    where 'N' is the no of records that u don't want to be in the cursor.....
    if u have doubt in this approach get back to me...

  • Weak REF CURSOR: discarding records?

    Hi,
    I'd like to discard the first N records from a weak REF CURSOR without having to specify the structure of the cursor. Is this possible?
    For example:
    LOOP
    FETCH results INTO garbagecan
    EXIT WHEN results%NOTFOUND;
    END LOOP;
    It seems that FETCH statement requires INTO to be specified with the correct structure.
    -Jerome
    null

    it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
    There is one way.....you can discard the first n records while assigning the query to cursor variable....
    Frame ur query that ur going to assocaite to the cursor in the following way....
    select * from (select rownum a, test.* from test) where a > N
    where 'N' is the no of records that u don't want to be in the cursor.....
    if u have doubt in this approach get back to me...

  • Stored PL/SQL function that returns REF CURSOR type

    Hello everyone,
    I've come through the following problem:
    1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
    PACKAGE PKG_LISTADOS AS
    TYPE tuplas IS REF CURSOR;
    /* Procedimientos exportados por el paquete */
    PROCEDURE inicializarModuloListados;
    FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
    RETURN tuplas;
    2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
    Connection conn;
    XmlDocument paramDef;
    conn=poolMgr.getConnection str_poolDBConnection);
    try
    CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
    cstmt.registerOutParameter(1, java.sql.Types.OTHER);
    cstmt.setString(2, "MONEDA");
    cstmt.executeQuery();
    ResultSet rs=(ResultSet)cstmt.getObject(1);
    catch(SQLException sqlE)
    3.- However, I can't make it OK, all the time I get the following error:
    SQL Error(17004), java.sql.SQLException: Non valid column type
    May anyone help me with this, thanks in advance:
    Miguel-Angel

    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by angelrip:
    Hello everyone,
    I've come through the following problem:
    1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
    PACKAGE PKG_LISTADOS AS
    TYPE tuplas IS REF CURSOR;
    /* Procedimientos exportados por el paquete */
    PROCEDURE inicializarModuloListados;
    FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
    RETURN tuplas;
    2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
    Connection conn;
    XmlDocument paramDef;
    conn=poolMgr.getConnection str_poolDBConnection);
    try
    CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
    cstmt.registerOutParameter(1, java.sql.Types.OTHER);
    cstmt.setString(2, "MONEDA");
    cstmt.executeQuery();
    ResultSet rs=(ResultSet)cstmt.getObject(1);
    catch(SQLException sqlE)
    3.- However, I can't make it OK, all the time I get the following error:
    SQL Error(17004), java.sql.SQLException: Non valid column type
    May anyone help me with this, thanks in advance:
    Miguel-Angel<HR></BLOCKQUOTE>
    Do something like the following:
    cstmt = conn.prepareCall("{call customer_proc(?, ?)}");
    //Set the first parameter
    cstmt.setInt(1, 40);
    //Register to get the Cursor parameter back from the procedure
    cstmt.registerOutParameter(2, OracleTypes.CURSOR);
    cstmt.execute();
    ResultSet cursor = ((OracleCallableStatement)cstmt).getCursor(2);
    while(cursor.next())
    System.out.println("CUSTOMER NAME: " + cursor.getString(1));
    System.out.println("CUSTOMER AGE: " + cursor.getInt(2));
    cursor.close();
    null

  • Ref cursor type

    Hello All,
    I have a small procedure like the following.
    CREATE OR REPLACE procedure PROC_DEPT_SALE(SALEC_CUR out sys_refcursor)
    as
    begin
    open sale for select * from dept_sale where dept_no='Z2341324';
    end;
    I just want to execute it from toad like
    exec PROC_DEPT_SALE( C1);
    In order to do that i need to have a sys_refcursor c1 created in my DB. I know that i can execute it as a plsql block like this
    DECLARE
    SALE SYS_REFCURSOR;
    BEGIN
    PROC_DEPT_SALE( SALE );
    END;
    Could anyone please let me know how can i create a TYPE REF cursor which is permanantly stored in the DB and then execute the proc the way i wanted to using the first statement.
    Thanks

    Actually, you had it correct with
    CREATE OR REPLACE package cur_type as
       TYPE ref_cur IS REF CURSOR;
    end;but you still need to declare a variable of the type to pass the the procedure since the procedure needs to have a cursor variable to open. Given your package, the call would be more like:
    DECLARE
       l_cur cur_type.ref_cur;
    BEGIN
       proc_dept_sale(l_cur);
       <do something with l_cur>
    END;Forget about the cursor for a minute and think through this example. If I have a procedure that looks like:
    CREATE PROCEDURE get_name (p_id    IN NUMBER,
                               p_name OUT VARCHAR2) AS
    BEGIN
       SELECT last_name||', '||first_name
       INTO p_name
       FROM employee
       WHERE emp_id = p_id;
    END;I can pass a literal value to the procedure for the p_id parameter (e.g. 42) or I could pass a variable holding a value.
    What do I need to pass to the procedure in p_name to get the name back out? A procedure returning a cursor is no different than this in concept.
    John

  • Ref cursor vs sys_refcursor

    What is the diffeerenece between ref cursor and sys_refcursor.in which scenarios we use ref cusor and sys_refcursor with example.For the performace point of view which is better.

    BluShadow wrote:
    SAMBIT RAY wrote:
    Hi,
    thanks for use ful difference.
    i got your difference between two but as per performace level which is better.plz suggestAs billy said they are all cursors.
    As my link highlights, a ref cursor of any sort is just a pointer to a query.
    SYS_REFCURSOR is just a synonym for the REF CURSOR type.
    There is no performance difference.Putting on my nit picking hat :-)
    Sys_refcursor is a named type of type refcursor. The $ORACLE_HOME/rdbms/admin/stdspec.sql ther is this line:
    /* Adding a generic weak ref cursor type */
    type sys_refcursor is ref cursor;Since it is in package standard we can use it without qualifying it with a package name, but
    declare
       l_cur sys_refcursor;is exactly the same as:
    reate package my_pack as
       type john_cursor is ref cursor;
    end;
    declare
       l_cur my_pack.john_cursor;Taking off my nit picking hat now.
    John

  • 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

  • TYPE REF CURSOR

    I have two packages (please see below). A procedure from the first package (TEST1) calls a procedure in the second package (TEST2), which has an output parameter of REF CURSOR TYPE.
    I am getting an error at compile time, in the calling procedure.
    Can anyone please help on finding out what am I missing here?
    Thank you in advance.
    - Ketan Bhuptani
    Here are the procedures:
    (1)
    CREATE OR REPLACE PACKAGE TEST1
    AS
    TYPE cursor_type_pass IS REF CURSOR;
    PROCEDURE call_cursor (result_flag OUT varchar2);
    END TEST1;
    CREATE OR REPLACE PACKAGE BODY TEST1
    AS
    PROCEDURE call_cursor (result_flag OUT varchar2) IS
    v_salary int;
    proc_cursor cursor_type_pass;
    CURSOR emp_cur is select empid from emp;
    BEGIN
    FOR emp_cur_var IN emp_cur
    LOOP
    test2.open_cursor(emp_cur_var.empid, proc_cursor);
    v_salary := proc_cursor.salary;
         -- getting an error Invalid reference to variable proc_cursor at this line
    END LOOP;
    END call_cursor;
    END TEST1;
    (2)
    CREATE OR REPLACE PACKAGE TEST2
    AS
    TYPE cursor_type_return IS REF CURSOR;
    PROCEDURE open_cursor (emp_id IN varchar2, out_cur OUT cursor_type_return);
    END TEST2;
    CREATE OR REPLACE PACKAGE BODY TEST2
    AS
    PROCEDURE open_cursor (emp_id IN varchar2, out_cur OUT cursor_type_return) IS
    BEGIN
    OPEN out_cur FOR
    select location, salary from emp_information where empid = emp_id;
    END open_cursor;
    END TEST2;
    create table emp_information
    (location varchar2(30), salary int, empid varchar2(10));
    create table emp
    (empid varchar2(10));

    Your scenario is not very clear to me, but let us do some test coding here, see if it helps you,SQL> create or replace package test_pkg1 as
      2  TYPE cursor_type1 IS REF CURSOR;
      3  procedure proc1;
      4  end;
      5  /
    Package created.
    SQL> create or replace package test_pkg2 as
      2  TYPE cursor_type2 IS REF CURSOR;
      3  procedure proc2(pCur IN OUT cursor_type2);
      4  end;
      5  /
    Package created.
    SQL> create or replace package body test_pkg2 as
      2  procedure proc2(pCur IN OUT cursor_type2) is
      3  begin
      4      open pCur for SELECT ename from  my_emp;
      5  end;
      6  end;
      7  /
    Package body created.
    SQL> create or replace package body test_pkg1 as
      2  procedure proc1 is
      3  vRefCur    cursor_type1;
      4  vEname     VARCHAR2(20);
      5  vRefCur2   test_pkg2.cursor_type2;
      6  begin
      7    test_pkg2.proc2(vRefCur); -- this is possible, but I do not like it.
      8    vRefCur2 := vRefCur; -- you can also do this, but you have no reason to do this
      9    loop
    10      fetch vRefCur2 into vEname;
    11      exit when vRefCur2%NOTFOUND;
    12      dbms_output.put_line(vEname);
    13    end loop;
    14    close vRefCur2;
    15  end;
    16  end;
    17  /
    Package body created.
    SQL> exec test_pkg1.proc1;
    SMITH
    ALLEN
    WARD
    JONES
    MARTIN
    BLAKE
    CLARK
    SCOTT
    KING
    TURNER
    ADAMS
    JAMES
    FORD
    MILLER
    PL/SQL procedure successfully completed.
    Let us make it simple,
    SQL> create or replace package body test_pkg1 as
      2  procedure proc1 is
      3  vRefCur    cursor_type1;
      4  vEname     VARCHAR2(20);
      5  --vRefCur2   test_pkg2.cursor_type2;
      6  begin
      7    test_pkg2.proc2(vRefCur);
      8    --vRefCur2 := vRefCur;
      9    loop
    10      fetch vRefCur into vEname;
    11      exit when vRefCur%NOTFOUND;
    12      dbms_output.put_line(vEname);
    13    end loop;
    14    close vRefCur;
    15  end;
    16  end;
    17  /
    Package body created.
    SQL> exec test_pkg1.proc1;
    SMITH
    ALLEN
    WARD
    JONES
    MARTIN
    BLAKE
    CLARK
    SCOTT
    KING
    TURNER
    ADAMS
    JAMES
    FORD
    MILLER
    PL/SQL procedure successfully completed.You can play with it number of different ways.
    Let me know what questions and we will take it from there.
    Thx,
    SriDHAR

  • How can I iterate over the columns of a REF CURSOR?

    I have the following situation:
    DECLARE
       text   VARCHAR2 (100) := '';
       TYPE gen_cursor is ref cursor;
       c_gen gen_cursor;
       CURSOR c_tmp
       IS
            SELECT   *
              FROM   CROSS_TBL
          ORDER BY   sn;
    BEGIN
       FOR tmp IN c_tmp
       LOOP
          text := 'select * from ' || tmp.table_name || ' where seqnum = ' || tmp.sn;
          OPEN c_gen FOR text;
          -- here I want to iterate over the columns of c_gen
          -- c_gen will have different number of columns every time,
          --        because we select from a different table
          -- I have more than 500 tables, so I cannot define strong REF CURSOR types!
          -- I need something like
          l := c_gen.columns.length;
          for c in c_gen.columns[1]..c_gen.columns[l]
          LOOP
              -- do something with the column value
          END LOOP;
       END LOOP;
    END;As you can see from the comments in the code, I couln'd find any examples on the internet with weak REF CURSORS and selecting from many tables.
    What I found was:
    CREATE PACKAGE admin_data AS
       TYPE gencurtyp IS REF CURSOR;
       PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
    END admin_data;
    CREATE PACKAGE BODY admin_data AS
       PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
       BEGIN
          IF choice = 1 THEN
             OPEN generic_cv FOR SELECT * FROM employees;
          ELSIF choice = 2 THEN
             OPEN generic_cv FOR SELECT * FROM departments;
          ELSIF choice = 3 THEN
             OPEN generic_cv FOR SELECT * FROM jobs;
          END IF;
       END;
    END admin_data;
    /But they have only 3 tables here and I have like 500. What can I do here?
    Thanks in advance for any help!

    The issue here is that you don't know your columns at design time (which is generally considered bad design practice anyway).
    In 10g or before, you would have to use the DBMS_SQL package to be able to iterate over each of the columns that are parsed from the query... e.g.
    CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
      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_rowcount  NUMBER := 0;
    BEGIN
      -- create a cursor
      c := DBMS_SQL.OPEN_CURSOR;
      -- parse the SQL statement into the cursor
      DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
      -- execute the cursor
      d := DBMS_SQL.EXECUTE(c);
      -- Describe the columns returned by the SQL statement
      DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
      -- Bind local return variables to the various columns based on their types
      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); -- Varchar2
          WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);      -- Number
          WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);     -- Date
        ELSE
          DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);  -- Any other type return as varchar2
        END CASE;
      END LOOP;
      -- Display what columns are being returned...
      DBMS_OUTPUT.PUT_LINE('-- Columns --');
      FOR j in 1..col_cnt
      LOOP
        DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
                                                                                  when 2 then 'NUMBER'
                                                                                  when 12 then 'DATE'
                                                         else 'Other' end);
      END LOOP;
      DBMS_OUTPUT.PUT_LINE('-------------');
      -- This part outputs the DATA
      LOOP
        -- Fetch a row of data through the cursor
        v_ret := DBMS_SQL.FETCH_ROWS(c);
        -- Exit when no more rows
        EXIT WHEN v_ret = 0;
        v_rowcount := v_rowcount + 1;
        DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
        DBMS_OUTPUT.PUT_LINE('--------------');
        -- Fetch the value of each column from the row
        FOR j in 1..col_cnt
        LOOP
          -- Fetch each column into the correct data type based on the description of the column
          CASE rec_tab(j).col_type
            WHEN 1  THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
            WHEN 2  THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
            WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
          ELSE
            DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
            DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
          END CASE;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('--------------');
      END LOOP;
      -- Close the cursor now we have finished with it
      DBMS_SQL.CLOSE_CURSOR(c);
    END;
    SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
    -- Columns --
    EMPNO - NUMBER
    ENAME - VARCHAR2
    DEPTNO - NUMBER
    SAL - NUMBER
    Row: 1
    EMPNO : 7782
    ENAME : CLARK
    DEPTNO : 10
    SAL : 2450
    Row: 2
    EMPNO : 7839
    ENAME : KING
    DEPTNO : 10
    SAL : 5000
    Row: 3
    EMPNO : 7934
    ENAME : MILLER
    DEPTNO : 10
    SAL : 1300
    PL/SQL procedure successfully completed.
    SQL> exec run_query('select * from emp where deptno = 10');
    -- Columns --
    EMPNO - NUMBER
    ENAME - VARCHAR2
    JOB - VARCHAR2
    MGR - NUMBER
    HIREDATE - DATE
    SAL - NUMBER
    COMM - NUMBER
    DEPTNO - NUMBER
    Row: 1
    EMPNO : 7782
    ENAME : CLARK
    JOB : MANAGER
    MGR : 7839
    HIREDATE : 09/06/1981 00:00:00
    SAL : 2450
    COMM :
    DEPTNO : 10
    Row: 2
    EMPNO : 7839
    ENAME : KING
    JOB : PRESIDENT
    MGR :
    HIREDATE : 17/11/1981 00:00:00
    SAL : 5000
    COMM :
    DEPTNO : 10
    Row: 3
    EMPNO : 7934
    ENAME : MILLER
    JOB : CLERK
    MGR : 7782
    HIREDATE : 23/01/1982 00:00:00
    SAL : 1300
    COMM :
    DEPTNO : 10
    PL/SQL procedure successfully completed.
    SQL> exec run_query('select * from dept where deptno = 10');
    -- Columns --
    DEPTNO - NUMBER
    DNAME - VARCHAR2
    LOC - VARCHAR2
    Row: 1
    DEPTNO : 10
    DNAME : ACCOUNTING
    LOC : NEW YORK
    PL/SQL procedure successfully completed.
    SQL>From 11g onwards, you can create your query as a REF_CURSOR, but then you would still have to use the DBMS_SQL package with it's new functions to turn the refcursor into a dbms_sql cursor so that you can then describe the columns in the same way.
    http://technology.amis.nl/blog/2332/oracle-11g-describing-a-refcursor
    Welcome to the issues that are common when you start to attempt to create dynamic code. If your design isn't specific then your code can't be either and you end up creating more work in the coding whilst reducing the work in the design. ;)

  • Ref cursors in Database adapter

    Hi,
    Is the database adapter capable of handling ref cursors as the datatype of the output parameters of a pl/sql procedure?
    For instance if I have the following in my package-spec:
    TYPE SomeRecordType IS RECORD
    ( record_pk mut_table.record_pk%TYPE
    , person_nr person_table.person_nr%TYPE
    , field_1 mut_table.field_1%type
    , field_2 mut_table.field_2%type
    , field_3 mut_table.field_3%type
    TYPE SomeCursorType IS REF CURSOR RETURN SomeRecordType;
    PROCEDURE read_records
    ( cursor_out OUT SomeCursorType
    , exception_code OUT number
    , exception_message OUT varchar2
    Can the database adapter call the read_records procedure?
    I've never seen this in any doc. I know it can't handle record types (that is in 10.1.2 it couldn't as far as I know). So I figure that the above is not possible.
    Thanks in advance.
    Regards,
    Martien

    We have successfully used a sys_refcursor OUT parameter for a database procedure call and which is used by a DBAdapter to return a single dataset.
    At the time I remember attempting to use a strongly typed ref cursor as the parameter. I think this is what you are attempting to do. I rejected this approach at the time as I was not able to do this. It was, in our case, as simple as using the system defined ref cursor type (i.e. weakly typed).
    The handling of the returned dataset was not immediately obvious, but can be handled by as fairly simple XSL transformation to a locally defined variable of the requisite xml structure. I won't describe in detail how to do it as it is specific to our process. Suffice to say the transformation loops over all result rows assign via a test to the correct result field in our local variable.
    e.g.
    <xsl:template match="/">
    <ns1:BatchRequest004>
    <xsl:for-each select="/db:OutputParameters/db:P_SCHSHP_REF_CUR/db:Row">
    <ns1:statusRqst>
    <xsl:if test='db:Column/@name = "ID"'>
    <xsl:attribute name="id">
    <xsl:value-of select="db:Column[1.0]"/>
    </xsl:attribute>
    </xsl:if>
    </ns1:statusRqst>
    </xsl:for-each>
    </ns1:BatchRequest004>
    HTH and that I haven't misidentified your problem.

  • Is there a different way to open a cursor for a ref cursor procedure?

    hello everybody
    i have two cursors, cur_a and cur_b, declared somewhere else in my application.
    These two cursors have the same fields, in the same order, and i have to treat both in the same way. So i wrote a routine that gets as input a ref cursor based on the cur_a rowtype, and i am trying to use this routine for both.
    The problem is that i am not able to open outside the routine the cursor in a different way than usual...
    the common method is :
    declare curs ref cursor ...
    begin
    open curs for (select *...)
    end;
    instead i would like to obtain something different
    declare curs ref cursor ...
    begin
    open curs for cur_a
    end;

    hi
    thanks for answering
    i wanted just to give a better idea, anyway you were near to get it.
    the only difference is that the two cursors are not written in dynamic sql, just like strings, but are real cursors.
    anyway, this is the version of the package i need, but i am not able to compile
    (your original code is commented and immediately below there is my code)
    CREATE OR REPLACE PACKAGE BODY mytest
    IS
    --cur_a VARCHAR2(200) := 'SELECT dummy FROM DUAL';
    CURSOR cur_a
    IS
    SELECT dummy
    FROM DUAL;
    --cur_b VARCHAR2(200) := 'SELECT ''fred'' FROM DUAL';
    CURSOR cur_b
    IS
    SELECT 'fred' fred
    FROM DUAL;
    TYPE t_cur_a IS REF CURSOR
    RETURN cur_a%ROWTYPE
    --PROCEDURE routine_a_b (p_cur SYS_REFCURSOR) IS
    PROCEDURE routine_a_b (p_cur t_cur_a)
    IS
    v_x VARCHAR2 (10);
    BEGIN
    LOOP
    FETCH p_cur
    INTO v_x;
    EXIT WHEN p_cur%NOTFOUND;
    DBMS_OUTPUT.put_line (v_x);
    END LOOP;
    END;
    PROCEDURE doit
    IS
    --v_curs SYS_REFCURSOR;
    v_curs t_cur_a;
    BEGIN
    NULL;
    -- open v_curs FOR cur_a;
    OPEN v_curs FOR cur_a;
    routine_a_b (v_curs);
    CLOSE v_curs;
    -- open v_curs FOR cur_b;
    -- routine_a_b(v_curs);
    -- close v_curs;
    END;
    END;
    the error is:
    cursor 'V_CURS' cannot be used in dynamic SQL OPEN statement
    i did read that if use weak ref cursor, it could work, so i declare the ref cursor type in this way:
    TYPE t_cur_a IS REF CURSOR;
    instead than
    TYPE t_cur_a IS REF CURSOR
    RETURN cur_a%ROWTYPE
    what i get is another error (in the open cursor command)
    PLS-00382: expression is of wrong type....
    but if i replace
    OPEN v_curs FOR cur_a;
    with
    OPEN v_curs for select dummy from dual;
    it works... but i already knew it.. :-)
    anyway, i used a work around to resolve it, so it's just philosophy

  • Dispalying output from a REF CURSOR

    Friends,
    I'm getting my self into indepth pl/sql and need some help from you to clear some basic concepts.
    create table MASTER_TABLE
    street_info varchar2(100),
    property_type varchar2(50) ------- i.e values here would be 'HOME_TABLE' ,'COM_PROP_TABLE' etc
    create table HOME_TABLE
    property_id char(5),
    prop_desc varchar2(100),
    cost varchar2(10),
    location varchar2(100)
    create table COM_PROP_TABLE
    property_id char(5),
    prop_desc varchar2(100),
    cost varchar2(10),
    location varchar2(100)
    I want to use a single procedure to open a weak REF CURSOR variable for the appropriate table based on the street address and display all information from that table.
    Here is what I want to to - execute a stored procedure which accepts 1 'in' paramter and 1 'in out ' parameter.
    IN paramter - accepts street address
    IN OUT paramter - depending on address , if it is related to 'Homes' , it should display all information from the HOME Table, else it will display information from the 'Commerical Property' table.
    create or replace package pack_address_info as
    type v_info_type ref cursor;
    end pack_address_info;
    create or replace procedure schema.sp_home_info(v_add in varchar2,v_show in out v_info_type)
    is
    home_type constant integer :=1;
    commercial_type constant integer :=2;
    cursor show_data_cur is
    select property_type from MASTER TABLE where street_info=v_add;
    var_cursor show_data_cur%rowtype;
    begin
    open show_data_cur;
    fetch show_data_cur into var_cursor;
    close show_data_cur;
    if var_cursor.property_type= HOME_TABLE
    then
    open v_show for
    select * from HOME_TABLE where location=v_add;
    elseif var_cursor.table_name = COM_PROP_TABLE
    then
    open v_show for
    select * from COM_PROP_TABLE where location=v_add;
    end if;
    end schema.sp_home_info;
    I can create the package and the stored proc ... but then ???? i'm stuck ;(
    Now , i don't know how to display the output from the HOME TABLE or the COM_PROP_TABLE depending on what the address is entered? Is this code correct. Can you please help me modify this code so that I can achieve my objective.
    This is an example from the book 'Oracle PL/SQL Programming, 4th Edition' under the 'CURSOR' section - 15.6
    Thanks for the help in advance.

    Here is one sample ->
    satyaki>
    satyaki>select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
    PL/SQL Release 10.2.0.3.0 - Production
    CORE    10.2.0.3.0      Production
    TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
    NLSRTL Version 10.2.0.3.0 - Production
    Elapsed: 00:00:00.02
    satyaki>
    satyaki>
    satyaki>CREATE OR REPLACE PACKAGE aaa_sat     
      2  AS       
      3     TYPE crs IS REF CURSOR RETURN emp%ROWTYPE;        
      4     FUNCTION fc_retcur (e_no IN NUMBER)
      5     RETURN crs;
      6  END aaa_sat;
      7  /
    Package created.
    Elapsed: 00:00:01.03
    satyaki>
    satyaki>
    satyaki>CREATE OR REPLACE PACKAGE BODY aaa_sat     
      2  AS       
      3    FUNCTION fc_retcur (e_no IN NUMBER)
      4    RETURN crs       
      5    IS         
      6      l_crs   crs;       
      7    BEGIN         
      8      OPEN l_crs FOR
      9      SELECT * FROM emp           
    10      WHERE empno = e_no;          
    11     
    12      RETURN l_crs;       
    13    END;
    14  END aaa_sat;
    15  /
    Package body created.
    Elapsed: 00:00:00.18
    satyaki>
    satyaki>
    satyaki>DECLARE       
      2    l_emp_rec   emp%ROWTYPE;       
      3    l_crs       aaa_sat.crs;     
      4  BEGIN       
      5    l_crs := aaa_sat.fc_retcur (7782);        
      6    LOOP          
      7      FETCH l_crs           
      8      INTO l_emp_rec;           
      9        EXIT WHEN l_crs%NOTFOUND;          
    10          DBMS_OUTPUT.put_line (l_emp_rec.ename);     
    11    END LOOP;        
    12    CLOSE l_crs;    
    13  END;
    14  /
    CLARK
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.40
    satyaki>
    satyaki>Got Me?
    Regards.
    Satyaki De.

  • [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

  • Stored procedure and ref cursor problem

    I am trying to create a stored procedure that can be used in Crystal Reports. To do this I have to create a package and a ref cursor. My SQL is below:
    --Package
    Create or Replace Package Test_Package
    as type test_type is ref cursor;
    end;
    --Procedure
    Create or Replace Procedure Test_Proc
    (test_cursor in out test_package.test_type,
    parameter in string
    as
    begin
    open test_cursor for
    select ClientName from apbpman.cv_client where clientref = parameter;
    end;
    --When trying to execute the SP in Oracle I use:-
    set serveroutput on
    declare
    test_cursor apbpman.test_package.test_type;
    resultset test_cursor%rowtype;
    begin
    apbpman.test_proc(test_cursor,'0096');
    if not test_cursor%isopen then
    dbms_output.put_line ('OK');
    else
    dbms_output.put_line ('Not OK');
    end if;
    fetch test_cursor into resultset;
    while test_cursor%found loop
    dbms_output.put_line(resultset.ClientName);
    fetch test_cursor into resultset;
    end loop;
    end;
    Whenever this runs I receive the following error reports:
    resultset test_cursor%rowtype;
    ERROR at line 3:
    ORA-06550: line 3, column 13:
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    ORA-06550: line 3, column 13:
    PL/SQL: Item ignored
    ORA-06550: line 11, column 25:
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    ORA-06550: line 11, column 2:
    PL/SQL: SQL Statement ignored
    ORA-06550: line 13, column 24:
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    ORA-06550: line 13, column 3:
    PL/SQL: Statement ignored
    ORA-06550: line 14, column 26:
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    ORA-06550: line 14, column 3:
    PL/SQL: SQL Statement ignored
    I have tried in vain to find a resolution to this but have failed. Please help.
    Thanks,
    Paul

    Unless you are running a really old version of Oracle, any weak ref cursor can just be declared SYS_REFCURSOR. Also, you can't use a weak ref cursor for %ROWTYPE. You can test the procedure in SQL*Plus by using it to populate a refcursor variable.

  • Dynamic sql and ref cursors URGENT!!

    Hi,
    I'm using a long to build a dynamic sql statement. This is limited by about 32k. This is too short for my statement.
    The query results in a ref cursor.
    Does anyone have an idea to create larger statement or to couple ref cursors, so I can execute the statement a couple of times and as an result I still have one ref cursor.
    Example:
    /* Determine if project is main project, then select all subprojects */
    for i in isMainProject loop
    if i.belongstoprojectno is null then
    for i in ProjectSubNumbers loop
    if ProjectSubNumbers%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    else
    for i in ProjectNumber loop
    if ProjectNumber%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    end if;
    end loop;
    /* Open ref cursor */
    open sql_output for SqlStatement;
    Thanks in advance,
    Jeroen Muis
    KCI Datasystems BV
    mailto:[email protected]

    Example for 'dynamic' ref cursor - dynamic WHERE
    (note that Reports need 'static' ref cursor type
    for building Report Layout):
    1. Stored package
    CREATE OR REPLACE PACKAGE report_dynamic IS
    TYPE type_ref_cur_sta IS REF CURSOR RETURN dept%ROWTYPE; -- for Report Layout only
    TYPE type_ref_cur_dyn IS REF CURSOR;
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn;
    END;
    CREATE OR REPLACE PACKAGE BODY report_dynamic IS
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn IS
    ref_cur_dyn type_ref_cur_dyn;
    BEGIN
    OPEN ref_cur_dyn FOR
    'SELECT * FROM dept WHERE ' | | NVL (p_where, '1 = 1');
    RETURN ref_cur_dyn;
    END;
    END;
    2. Query PL/SQL in Reports
    function QR_1RefCurQuery return report_dynamic.type_ref_cur_sta is
    begin
    return report_dynamic.func_dyn (:p_where);
    end;
    Regards
    Zlatko Sirotic
    null

Maybe you are looking for