Nested Cursor

Dears,
I have the below requirement:
Table A has columns a1 & a2, a3 and table B has column a1, b1 & b2. Retrieve a1, a2, a3 & sum of a3 for the same a1 values into resultset r1. Then iterate r1 & for each distinct a1, find the max value of b1 & the corresponding b2, put the result into resultset r2. Return r2
Please advise how I can achieve this using oracle procedure/function. This solution will help me to improve th performance of my application a lot

SQL> create table a (
  2    a1 integer,
  3    a2 varchar2(20),
  4    a3 number
  5  );
Table created.
SQL> insert into a(a1, a2, a3) values(1, '111', 123);
1 row created.
SQL> insert into a(a1, a2, a3) values(1, '22', 1);
1 row created.
SQL> insert into a(a1, a2, a3) values(1, '1', 2);
1 row created.
SQL> insert into a(a1, a2, a3) values(2, 'dd', 33);
1 row created.
SQL> insert into a(a1, a2, a3) values(3, 'ggg', 77);
1 row created.
SQL> insert into a(a1, a2, a3) values(3, 'jj', 999);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from a;
        A1 A2                           A3
         1 111                         123
         1 22                            1
         1 1                             2
         2 dd                           33
         3 ggg                          77
         3 jj                          999
6 rows selected.
SQL> create table b(
  2    a1 integer,
  3    b1 number,
  4    b2 varchar2(20)
  5  );
Table created.
SQL> insert into b(a1, b1, b2) values(1, 22, 'ggg');
1 row created.
SQL> insert into b(a1, b1, b2) values(1, 2, 'g');
1 row created.
SQL> insert into b(a1, b1, b2) values(2, 5, '777');
1 row created.
SQL> insert into b(a1, b1, b2) values(2, 6, '555');
1 row created.
SQL> insert into b(a1, b1, b2) values(2, 7, '666');
1 row created.
SQL> insert into b(a1, b1, b2) values(3, 66, 'ggg');
1 row created.
SQL> insert into b(a1, b1, b2) values(3, 22, 'jjj');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from b;
        A1         B1 B2
         1         22 ggg
         1          2 g
         2          5 777
         2          6 555
         2          7 666
         3         66 ggg
         3         22 jjj
7 rows selected.
SQL> with r1 as (
  2    select a.*,
  3      sum(a3) over(partition by a1) as sum_a3
  4    from a
  5  ),
  6  r2 as (
  7    select a1,
  8      max(b1) as b1,
  9      min(b2) keep (dense_rank last order by b1) as b2
10    from b
11    where a1 in (select a1 from r1)
12    group by a1
13  )
14  select * from r2;
        A1         B1 B2
         1         22 ggg
         2          7 666
         3         66 gggNot clear why do you need r1 if r2 is the only data to be returned. It can be calculated much simpler:
SQL> select a1,
  2    max(b1) as b1,
  3    min(b2) keep (dense_rank last order by b1) as b2
  4  from b
  5  where a1 in (select a1 from a)
  6  group by a1;
        A1         B1 B2
         1         22 ggg
         2          7 666
         3         66 gggRegards,
Dima
Message was edited by:
DimaCit

Similar Messages

  • Problem with generating xml and nested cursor (ora-600)

    I have a problem with generating xml (with dbms_xmlquery or xmlgen) and nested cursors.
    When I execute the following command, I get a ORA-600 error:
    select dbms_xmlquery.getxml('select mst_id
    , mst_source
    , cursor(select per.*
    , cursor(select ftm_fdf_number
    , ftm_value
    from t_feature_master
    where ftm_mstr_id = pers_master_id ) as features
    from t_person per
    where pers_master_id = mst_id ) as persons
    from f_master
    where mst_id = 3059435')
    from dual;
    <?xml version = '1.0'?>
    <ERROR>oracle.xml.sql.OracleXMLSQLException: ORA-00600: internal error code, arguments: [kokbnp2], [1731], [], [], [], [], [], []
    </ERROR>
    The problem is the second cursor (t_feature_master).
    I want to generate this:
    <master>
    <..>
    <persons>
    <..>
    <features>
    <..>
    </features>
    </persons>
    <persons>
    <..>
    <features>
    <..>
    </features>
    </persons>
    </master>
    If i execute the select-statement in sql-plus, then I get the next result.
    MST_ID MST_SOURCE PERSONS
    3059435 GG CURSOR STATEMENT : 3
    CURSOR STATEMENT : 3
    PERS_MASTER_ID PERS_TITLE PERS_INITI PERS_FIRSTNAME PERS_MIDDL PERS_LASTNAME
    3059435 W. Name
    CURSOR STATEMENT : 15
    FTM_FDF_NUMBER FTM_VALUE
    1 [email protected]
    10 ....
    I use Oracle 8.1.7.4 with Oracle XDK v9.2.0.5.0.
    Is this a bug and do somebody know a workaround?

    Very simple...Drop all type objects and nested tables and create them again. You will get no error. I'll explain the reason later.

  • Problem with XSU and DataSources with nested cursors?

    We are having a problem with the xsu libraries (OracleXMLQuery) using nested cursor syntax. The class returns nicely nested xml document when a database connection is established in the traditional/legacy manner of "class.forName(); DriverManager.registerDriver();" .
    However, when using a DataSouce object within a J2EE container, we get an xml document back that only represents the main level of the resultset with datatypes + memory addresses for the cursor fields (instead of the expected nested xml elements).
    Any thoughts?
    BTW, we are using the iPlanet Application Server with an Oracle 9i database.
    for instance:
    SELECT a, b, CURSOR(select m, n, o
    from table2
    where table1.x = table2.y),
    d, e, f
    FROM table1
    WHERE table1.name = 'Matt'

    Somebody please answer this question?

  • Stored Proc to create XML (using nested cursors)?

    From previous posts and from the
    documentation for XSQL I have
    discovered the joys of the
    CURSOR operator to create
    nested tables: i.e:
    SELECT dname,
    CURSOR (SELECT ename, sale....) as employees
    FROM dept
    However, I can not find any other
    documentation on how to program (PL/SQL)
    this functionality.
    I would like to use XSQL as
    it is exactly what I need, but
    I can not because my client does
    not want to use Java and they
    require IIS, but do not want to
    use JRUN, etc... (I tried this
    first).
    Since I only need to do an XML
    dump to a variable for processing
    by other parts of the program, life
    is fairly easy. I have already done
    this using Microsoft Data Shapes in
    VB (client does not want VC++ either...)
    However this was slow.
    In order to speed things up I want to
    create a stored procedure in Oracle to
    dump out the XML hierarchy to a variable given
    an SQLQuery input. If I use
    nested CURSORS this should be very easy.
    I would like to create a recursive PL/SQL
    function to handle this, but I have the
    following questions:
    1) I want the function to have an
    input of an open cursor,
    My plan is to detect the column
    type, when it is a nested cursor
    I would recurse with the open cursor
    to handle the nested cursor.
    2) I can not find a reference on to
    programatically handle "untyped collections
    based on an SQL statement" in anything
    other than the XSQL documentation.
    I am assuming that I can detect the
    column type of nested cursor somehow
    and then recurse on this to handle
    dump the recordset to an XML tagset.
    But I wuold like to find some documentation
    or examples on the calls, type statements,
    etc....

    I think the CURSOR() thing is an invention of the XSQL Servlet; not available elsewhere.
    You can accomplish nesting via user defined types and object views, using the "cast(multiset())" syntax, which is not documented particularly well either. This does require some setup, and so is not particularly dynamic.

  • Nested Cursors

    I'm trying to convert my look-up table data. But before I update the actual look-up tables themselves, I want to update the tables that "look" to the look-up tables. Hard to describe, but I posted on something similar to this before. I thought I had it worked out, but it's more complicated than I realized.
    I want to use a table I've created just for this called MATRIX_DEPT which houses the old and new dept. codes. Then my proc is supposed to look to the data dictionary table and update all the tables in the database that look to the DEPT table with the new dept. codes. I swear this ALMOST works!!
    Here's the code so far:
    CREATE OR REPLACE PROCEDURE CONVERSION IS
    CURSOR look_up IS
    SELECT TABLENAME, COLUMNNAME
    FROM DICTIONARY
    WHERE REFTABLE = 'DEPT';
    CURSOR matrix IS
    SELECT OLD_CODE, NEW_CODE
    FROM DEPT_MATRIX
    ORDER BY OLD_CODE;
    DDTBL VARCHAR2(30);
    DDCOL VARCHAR2(30);
    OLDCODE VARCHAR2(10);
    NEWCODE VARCHAR2(10);
    begin
    OPEN look_up;
    LOOP
    FETCH look_up INTO DDTBL, DDCOL;
    EXIT WHEN look_up%NOTFOUND;
    OPEN matrix;
    LOOP
    FETCH matrix INTO OLDCODE, NEWCODE;
    EXIT WHEN matrix%NOTFOUND;
    UPDATE DDTBL SET DDCOL = NEWCODE WHERE DDCOL = OLDCODE;
    END LOOP;
    CLOSE matrix;
    END LOOP;
    COMMIT;
    CLOSE look_up;
    END;
    Keep in mind - this ALMOST works!! The only part that's not working is the update statement. If I comment out the update statement and instead output the new and old codes, then the script appears to work exactly as coded.
    I looked into DBMS_SQL.PARSE() but couldn't get it work for this instance. All the examples I found on it were for just one cursor, not 2 nested cursors.
    Would it be better just to spool the update out and then run THAT script. Kind doesn't seem as slick though.

    How about using sql to create the update statements...
    SQL> CREATE TABLE t1 (dept VARCHAR2(10), c1 VARCHAR2(100));
    Table created.
    SQL> CREATE TABLE t2 (dept VARCHAR2(10), c2 VARCHAR2(100));
    Table created.
    SQL> CREATE TABLE t3 (dept VARCHAR2(10), c3 VARCHAR2(100));
    Table created.
    SQL> 
    SQL> CREATE TABLE dept_matrix(old_code VARCHAR2(10), new_code VARCHAR2(10));
    Table created.
    SQL> 
    SQL> INSERT INTO dept_matrix VALUES('o1','n1');
    1 row created.
    SQL> INSERT INTO dept_matrix VALUES('o2','n2');
    1 row created.
    SQL> INSERT INTO dept_matrix VALUES('o3','n3');
    1 row created.
    SQL> INSERT INTO dept_matrix VALUES('o4','n4');
    1 row created.
    SQL> 
    SQL> SELECT ''' when '''''||old_code||''''' then '''''||new_code||'''''''||-' FROM dept_matrix;
    '''WHEN'''''||OLD_CODE||'''''THEN'''''||NEW_C
    ' when ''o1'' then ''n1'''||-
    ' when ''o2'' then ''n2'''||-
    ' when ''o3'' then ''n3'''||-
    ' when ''o4'' then ''n4'''||-
    SQL> var mycase varchar2(1000);
    SQL> exec :mycase := ' set dept = case dept '||-
     ' when ''o1'' then ''n1'''||-
     ' when ''o2'' then ''n2'''||-
     ' when ''o3'' then ''n3'''||-
     ' when ''o4'' then ''n4'''||-
     ' end;';
    PL/SQL procedure successfully completed.
    SQL> SELECT 'update '||table_name||:mycase FROM user_tab_columns WHERE column_name = 'DEPT';
    'UPDATE'||TABLE_NAME||:MYCASE
    update T1 set dept = case dept  when 'o1' then 'n1' when 'o2' then 'n2' when 'o3' then 'n3' when 'o4'
    update T2 set dept = case dept  when 'o1' then 'n1' when 'o2' then 'n2' when 'o3' then 'n3' when 'o4'
    update T3 set dept = case dept  when 'o1' then 'n1' when 'o2' then 'n2' when 'o3' then 'n3' when 'o4'
    3 rows selected.
    SQL>

  • Hibernate Oracle nested CURSOR

    Hi All,
    I'm connecting to an Oracle database, and accessing a function that returns a SYS_REFCURSOR. I can succesfully map the function using the following syntax:
    @NamedNativeQuery( name = "blah_list"
    , query = "{ call blah__function(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}"
    , resultClass = blah.class
    , hints = { @QueryHint(name = "org.hibernate.callable", value = "true")
    , @QueryHint(name = "org.hibernate.readOnly", value = "true")
    I can access the resultset it returns.
    The issue is, within the resultset, there are nested CURSOR's.. ie:
    SELECT my_column1, my_column2
    ,CURSOR (
    SELECT my_column1
    FROM my_table2
    WHERE blah = blah ) column3
    FROM my_table1
    My question is, how do I loop through the resultset from the nested cursor? In the above, I can succesfully iterate through my_column1 and my_column2, but I can't through column3... Any ideas?!
    Thanks very much! :)

    What do you have so far?
    Perhaps this will point you in the right direction.
        -- Return a ref cursor as an output parameter.
        CallableStatement cs = conn.prepareCall("begin open :c for select dummy, cursor(select dummy from dual) from dual; end;");
        cs.registerOutParameter(1, OracleTypes.CURSOR);
        cs.execute();
        -- Treat the output parameter as a result set.
        -- Column 1: String
        -- Column 2: Cursor (ResultSet)
        ResultSet rs = (ResultSet)cs.getObject(1);
        while(rs.next()) {
          String x = rs.getString(1);
          System.out.println("Column 1: " + x);
          -- Second column is a result set
          -- Column 1: String
          ResultSet c = (ResultSet)rs.getObject(2);
          while(c.next()) {
            String x2 = c.getString(1);
            System.out.println(" - Column 2: " + x2);
        cs.close();
    Column 1: X
    - Column 2: X

  • Stored procedure: nested cursor problem

    Hey folks,
    i am really having a hard time trying to figure out how nested cursors work.
    What i want to do:
    -> Do one select statement and process the yielded rows with one cursor
    -> Do another select statement depending on the first cursor
    The code is quite simple, the beginning of the stored procedure is:
    create or replace
    PROCEDURE extractEntireMD IS
    CURSOR curTemplateUnitId IS
    SELECT
    tu.externalident,
    tu.templateunitid
    FROM
    templateunit tu
    WHERE
    tu.templateunitid = 100007;
    CURSOR curPartTypeId(templateUnitID IN varchar2) IS
    SELECT
    tpt.parttypeid
    FROM
    templateparttype tpt
    WHERE
    tpt.templateunitid = templateUnitID;
    From what i have read, this seems to be right.
    No i want to use this code like this:
    BEGIN
    FOR valInCurTemplateUnitId IN curTemplateUnitId LOOP
    DBMS_OUTPUT.PUT_LINE('ExtIdent: ' || valInCurTemplateUnitId.externalident);
    DBMS_OUTPUT.PUT_LINE('templateunitid: ' || valInCurTemplateUnitId.templateunitid);
    FOR valIncurPartTypeId IN curPartTypeId(valInCurTemplateUnitId.templateunitid) LOOP
    DBMS_OUTPUT.PUT_LINE('PartTypeId: ' || valIncurPartTypeId.parttypeid);
    END LOOP;
    END LOOP;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('No such data ');
    END;
    The problem:
    I seem to be doing something wrong, because Oracle does not heed the argument which i give to the second cursor from the first cursor:
    CURSOR curPartTypeId(templateUnitID IN varchar2) IS
    which i call via:
    FOR valIncurPartTypeId IN curPartTypeId(valInCurTemplateUnitId.templateunitid)
    Instead, oracle prints out __all__ templateunitids.
    If I modify the second cursor with a constant argument like this:
    CURSOR curPartTypeId(templateUnitID IN varchar2) IS
    SELECT DISTINCT
    tpt.parttypeid
    FROM
    templateparttype tpt
    WHERE
    tpt.templateunitid = 100007;
    The result is correct. So it seems like oracle simply disregards the parameter i am giving him for the second cursor.
    What am i doing wrong?

    > i am really having a hard time trying to figure out how nested cursors work.
    Good. I trust that this will result in the realisation that it is an idiotic thing to emulate the features of the SQL engine in PL/SQL. Only a fool thinks the he/she can outprogram and outsmart the SQL engine, and do things like nested loop joins better and faster in PL/SQL.
    Use SQL for the purpose it was designed. Use PL/SQL for the purpose it was designed.
    Joining of data? That is prime function and feature of SQL. Not PL/SQL.

  • Xmlgen.getxml Nested Cursors with LONG RAW and BLOB Data Types

    I am trying to use a nested cursor with xmlgen.getxml that has a long raw or blob column. In either case, it will not return to me any data in the xml document pertaining to that LONG RAW or BLOB column. If I do not use a nested cursor, it works fine.
    Example:
    SELECT xmlgen.getxml('SELECT x, CURSOR(SELECT y FROM y_tab WHERE y_tab.x_id = x_tab.x_id) y FROM x_tab') FROM dual;
    This will not produce the information I am after.
    However, simply running:
    SELECT xmlgen.getxml('SELECT y FROM y_tab WHERE y_tab.x_id = <somevalue>') FROM dual;
    Works???
    Any ideas out there? Does anyone know if DBMS_XMLQUERY has this limitation?
    Thanks,
    Brad

    It doesn't appear that I am able to attach the PDF files.  Can you supply your email (or I can supply mine) so I can send you the three files:
    1.)  A good PDF (manually extracted from our old application)
    2.)  Dump of the same PDF file (includes header/footer info)
    3.)  A partially fixed PDF file (but some of the pictures / pages are cut off - specifically pages 3,5,9,10,12,14)
    The way that we have tried to fix the file (in example 3 above) is the following:
    a.)  Find the First Occurrence of "%PDF-"
    b.)  Find the Last Occurrence of "%%EOF"
    c.)  if the first "%PDF-" is found AND the last "%%EOF" is found, then
       i.)  Remove all data before the first %PDF-
       ii.)  Remove all data after the last %%EOF
    Let me know if you need any other information.
    Thanks,
    Mike

  • How to write nested cursor for Adv. Collections dunning letter query

    I am trying to write a query for Advanced Collections duninng letters. Some accounts for this customer have invoices for more than one currency. In order to find all of the invoices this query works:
    select to_char(sysdate, 'MM/DD/YYYY') currsysdate,
    decode((per.person_first_name || per.person_last_name), null, ARPT_SQL_FUNC_UTIL.get_lookup_meaning('RESPONSIBILITY', 'APS'), per.person_first_name) first_name,
    per.person_last_name last_name,
    org.party_name org_name,
    loc.address1 address1,
    loc.address2 address2,
    loc.city city,
    loc.state state,
    loc.postal_code postal_code,
    per.person_first_name first_name1,
    (select sum(aps.amount_due_remaining)
    from
    iex_delinquencies_all dd,
    ar_payment_schedules_all aps
    where
    dd.payment_schedule_id = aps.payment_schedule_id and
    dd.party_cust_id = org.party_id and
    dd.cust_account_id = 255849 and
    dd.customer_site_use_id = 13071) total_amount_due_remaining,
    to_char(sysdate+7, 'MM/DD/YYYY') required_pay_date,
    rs.source_email collector_email,
    arc.alias collector_name,
    arc.telephone_number collector_phone,
    ar.account_number,
    cursor
    (select
    ct.trx_number invoice_number,
    to_char(ar.due_date, 'MM/DD/YYYY') due_date,
    ar.amount_due_remaining amount_due_remaining,
    ar.invoice_currency_code invoice_currency_code
    from
    iex_delinquencies_all d,
    ar_payment_schedules_all ar,
    ra_customer_trx_all ct
    where
    d.party_cust_id = org.party_id
    and d.cust_account_id = 255849
    and d.customer_site_use_id = 13071
    and d.payment_schedule_id = ar.payment_schedule_id
    and d.status = 'DELINQUENT'
    and ar.customer_trx_id = ct.customer_trx_id
    and ar.amount_due_remaining <> 0
    ) as payment_history
    from
    HZ_LOCATIONS loc
    ,hz_parties org
    ,hz_parties per
    ,jtf_rs_resource_extns rs
    ,ar_collectors arc
    ,hz_cust_accounts ar
    where
    loc.location_id = 11600
    and org.party_id= 255849
    --and per.party_id = nvl(:CONTACT_ID, org.party_id)
    and per.party_id = 255849
    and arc.resource_id = rs.resource_id
    and rs.RESOURCE_ID = 100022224
    and ar.cust_account_id = 182399
    But this assumes there is only one invoice currency but there isn't. Now I need to loop through all the distinct currencies in the ar_payment_schedules table so I was trying something like this:
    select to_char(sysdate, 'MM/DD/YYYY') currsysdate,
    decode((per.person_first_name || per.person_last_name), null, ARPT_SQL_FUNC_UTIL.get_lookup_meaning('RESPONSIBILITY', 'APS'), per.person_first_name) first_name,
    per.person_last_name last_name,
    org.party_name org_name,
    loc.address1 address1,
    loc.address2 address2,
    loc.city city,
    loc.state state,
    loc.postal_code postal_code,
    per.person_first_name first_name1,
    (select sum(aps.amount_due_remaining)
    from
    iex_delinquencies_all dd,
    ar_payment_schedules_all aps
    where
    dd.payment_schedule_id = aps.payment_schedule_id and
    dd.party_cust_id = org.party_id and
    dd.cust_account_id = 255849 and
    dd.customer_site_use_id = 13071) total_amount_due_remaining,
    to_char(sysdate+7, 'MM/DD/YYYY') required_pay_date,
    rs.source_email collector_email,
    arc.alias collector_name,
    arc.telephone_number collector_phone,
    ar.account_number,
    cursor
    (select distinct ar.invoice_currency_code invoice_currency_code
    from
    iex_delinquencies_all d,
    ar_payment_schedules_all ar,
    ra_customer_trx_all ct
    where
    d.party_cust_id = org.party_id
    and d.cust_account_id = 255849
    and d.customer_site_use_id = 13071
    and d.payment_schedule_id = ar.payment_schedule_id
    and d.status = 'DELINQUENT'
    and ar.customer_trx_id = ct.customer_trx_id
    and ar.amount_due_remaining <> 0
    cursor
    (select
    ct.trx_number invoice_number,
    to_char(ar.due_date, 'MM/DD/YYYY') due_date,
    ar.amount_due_remaining amount_due_remaining,
    --ar.invoice_currency_code invoice_currency_code
    from
    iex_delinquencies_all d,
    ar_payment_schedules_all ar,
    ra_customer_trx_all ct
    where
    d.party_cust_id = org.party_id
    and d.cust_account_id = 255849
    and d.customer_site_use_id = 13071
    and d.payment_schedule_id = ar.payment_schedule_id
    and d.status = 'DELINQUENT'
    and ar.customer_trx_id = ct.customer_trx_id
    and ar.amount_due_remaining <> 0
    and ar.invoice_currency_code = invoice_currency_code
    ) as payment_history
    ) as g_currency
    from
    HZ_LOCATIONS loc
    ,hz_parties org
    ,hz_parties per
    ,jtf_rs_resource_extns rs
    ,ar_collectors arc
    ,hz_cust_accounts ar
    where
    loc.location_id = 11600
    and org.party_id= 255849
    --and per.party_id = nvl(:CONTACT_ID, org.party_id)
    and per.party_id = 255849
    and arc.resource_id = rs.resource_id
    and rs.RESOURCE_ID = 100022224
    and ar.cust_account_id = 182399
    But I am getting missing right parenthesis error which leads me to think I am writing this correctly.

    Note the name of this forum is "SQL Developer *(Not for general SQL/PLSQL questions)*", so only for issues with the SQL Developer tool. Please post these questions under the dedicated SQL And PL/SQL forum (you've posted there before).
    Regards,
    K.

  • Help with building nested cursors

    Hello all,
    In one of our plsql procedures, we return a cursor of cursors that looks like this:
    OPEN main_cursor FOR
      SELECT
        CURSOR (
          SELECT query1
        ) c1,
        CURSOR (
          SELECT query2
        ) c2
      FROM DUAL;Now, we need to add a new condition that changes query1 into either query1a or query1b (depending of the condition). An easy refactor was done to the code as follows:
    IF (some_condition) THEN
      OPEN main_cursor FOR
        SELECT
          CURSOR (
            SELECT query1a
          ) c1,
          CURSOR (
            SELECT query2
          ) c2
        FROM DUAL;
    ELSE
      OPEN main_cursor FOR
        SELECT
          CURSOR (
            SELECT query1b
          ) c1,
          CURSOR (
            SELECT query2
          ) c2
        FROM DUAL;However, as you can see, query2 is duplicated in the if and else clauses. I wasn't able to find a way to avoid this duplication. Any ideas someone?
    Also, note that the difference between query1a and query1b is a table join.
    Thanks in advance,
    wf

    OPEN FOR allows for dynamic SQL where statements are put together by concatenating strings.
    http://www.morganslibrary.org/reference/ref_cursors.html
    Look at the demo of a Weakly Typed REF CURSOR.

  • Open a cursor containing a nested table?

    I have created a table with several nested tables by following the examples in: http://otn.oracle.com/docs/products/oracle8/doc_index.htm
    I am now trying to query one of these nested tables using the techniques that are described.
    The two techniques are (page 31 of above reference):
    (1) "Flattened" query.
    (2) Nested cursor
    Both of these techniques work by simple SQL queries in SQl*Plus.
    However, I get compilation errors when using identical queries when trying to open and return a cursor in a stored procedure.
    Can you please help? Is this supported in 8.1.7?
    Is there a better way to query and return data using OO4O to a windows client program?
    If necessary, I would be glad to provide code samples.
    Thank you,
    Casey Cummings

    Here is a copy of my test code for the question that I posted. Any help on how I can get nested table data back to a windows client would be greatly apreciated.
    Thank you.
    Casey Cummings
    --DDL.
    --Original table.
    CREATE TABLE MY_TABLE(
    MY_KEY INTEGER,
    MY_DATA VARCHAR2(2000));
    --Basic Object types.
    CREATE TYPE MY_NUMERIC_OBJTYP AS OBJECT(
    SEQUENCE INTEGER,
    DATUM NUMBER);
    CREATE TYPE MY_TEXT_OBJTYP AS OBJECT(
    SEQUENCE INTEGER,
    DATUM VARCHAR2(255));
    --Table type. Table of basic objects.
    CREATE TYPE MY_NUMERIC_TABTYP AS TABLE OF MY_NUMERIC_OBJTYP;
    CREATE TYPE MY_TEXT_TABTYP AS TABLE OF MY_TEXT_OBJTYP;
    --Add nested tables to original table.
    ALTER TABLE MY_TABLE ADD(
    MY_NUMERIC_NTAB MY_NUMERIC_TABTYP)
    NESTED TABLE MY_NUMERIC_NTAB STORE AS MY_NUMERIC_TABLE;
    ALTER TABLE MY_TABLE ADD(
    MY_TEXT_NTAB MY_TEXT_TABTYP)
    NESTED TABLE MY_TEXT_NTAB STORE AS MY_TEXT_TABLE;
    --Insert test data in the main, unnested table.
    INSERT INTO MY_TABLE(
    MY_KEY, MY_DATA
    )VALUES(
    1001, 'RECORD-1001');
    COMMIT;
    --Create the actual nested tables.
    UPDATE MY_TABLE SET
    MY_NUMERIC_NTAB = MY_NUMERIC_TABTYP();
    UPDATE MY_TABLE SET
    MY_TEXT_NTAB = MY_TEXT_TABTYP();
    COMMIT;
    --Insert test data into the nested tables.
    INSERT INTO TABLE(
    SELECT X.MY_NUMERIC_NTAB
    FROM MY_TABLE X
    WHERE MY_KEY = 1001
    )VALUES(
    1,901);
    INSERT INTO TABLE(
    SELECT X.MY_NUMERIC_NTAB
    FROM MY_TABLE X
    WHERE MY_KEY = 1001
    )VALUES(
    2,902);
    INSERT INTO TABLE(
    SELECT X.MY_NUMERIC_NTAB
    FROM MY_TABLE X
    WHERE MY_KEY = 1001
    )VALUES(
    3,903);
    INSERT INTO TABLE(
    SELECT X.MY_TEXT_NTAB
    FROM MY_TABLE X
    WHERE MY_KEY = 1001
    )VALUES(
    1,'ONE');
    COMMIT;
    BOTH OF THESE QUERYS WORK WHEN ENTERED IN SQL*PLUS.
    --"FLATTENED" QUERY
    SELECT X.MY_DATA, N.SEQUENCE, N.DATUM, T.SEQUENCE, T.DATUM
    FROM
    MY_TABLE X,
    TABLE(X.MY_NUMERIC_NTAB) N,
    TABLE(X.MY_TEXT_NTAB) T
    WHERE X.MY_KEY = 1001;
    --"CURSOR" QUERY
    SELECT X.MY_DATA,
    CURSOR(
    SELECT *
    FROM TABLE (MY_NUMERIC_NTAB) ),
    CURSOR(
    SELECT *
    FROM TABLE (MY_TEXT_NTAB) )
    FROM MY_TABLE X
    WHERE X.MY_KEY = 1001;
    CREATE OR REPLACE PACKAGE MANAGE_TEST AS
    TYPE THE_CURSOR IS REF CURSOR;
    PROCEDURE QUERY_TEST(
    MY_CURSOR IN OUT THE_CURSOR
    END;
    CREATE OR REPLACE PACKAGE BODY MANAGE_TEST AS
    PROCEDURE QUERY_TEST(
    MY_CURSOR IN OUT THE_CURSOR
    AS
    BEGIN
    OPEN MY_CURSOR FOR
    --"FLATTENED" QUERY
    SELECT X.MY_DATA, N.SEQUENCE, N.DATUM, T.SEQUENCE, T.DATUM
    FROM
    MY_TABLE X,
    TABLE(X.MY_NUMERIC_NTAB) N,
    TABLE(X.MY_TEXT_NTAB) T
    WHERE X.MY_KEY = 1001;
    END;
    END;
    *****************Errors:
    LINE/COL ERROR
    8/5 PL/SQL: SQL Statement ignored
    11/13 PLS-00201: identifier 'X.MY_NUMERIC_NTAB' must be declared
    CREATE OR REPLACE PACKAGE BODY MANAGE_TEST AS
    PROCEDURE QUERY_TEST(
    MY_CURSOR IN OUT THE_CURSOR
    AS
    BEGIN
    OPEN MY_CURSOR FOR
    --"CURSOR" QUERY
    SELECT X.MY_DATA,
    CURSOR(
    SELECT *
    FROM TABLE (MY_NUMERIC_NTAB) ),
    CURSOR(
    SELECT *
    FROM TABLE (MY_TEXT_NTAB) )
    FROM MY_TABLE X
    WHERE X.MY_KEY = 1001;
    END;
    END;
    *****************Errors:
    LINE/COL ERROR
    11/11 PLS-00103: Encountered the symbol "SELECT" when expecting one of
    the following:
    ( ) - + mod not null others <an identifier>
    <a double-quoted delimited-identifier> <a bind variable>
    table avg count current exists max min prior sql stddev sum
    variance execute multiset the both leading trailing forall
    year month DAY_ HOUR_ MINUTE_ second TIMEZONE_HOUR_
    TIMEZONE_MINUTE_ time timestamp interval date
    <a string literal with character set specification>
    <a number> <a single-quoted SQL stri
    12/41 PLS-00103: Encountered the symbol "," when expecting one of the
    following:
    ; return returning and or
    null

  • Maximum Open Cursors Exceeded problem in XSQL

    Hi,
    We are processing an XSQL page by calling XSQLRequest.process() programatically within our application. Within the XSQL page there are several queries which involve multiple nested CURSOR expressions... when the query returns enough rows we are running into the error "ORA-00604: error occurred at recursive SQL level 1 ORA-01000: maximum open cursors exceeded".
    When searching this forum I have seen many (old) postings regarding this error and a bug in the XDK... seems like it was some time ago, but while we set about improving the structure of our XSQL page (or increasing the max open cursor init parameter currently at 500 or both) can anyone confirm that this bug no longer exists?
    Also, any general suggestions on working around this limit rather than increasing it? We have considered splitting up our queries into smaller queries (and merging the results via XSLT) and closing cursors during the session explicitly by issuing commits within the XSQL page... but any better ideas?
    Thanks,
    Bob

    I have found this max open cursors problem to be related to Statement object not being closed. This presents a problem for the use of PreparedStatements, because they are only useful if you can keep them open and resuse them. However, in doing so, each iteration through the PreparedStatement creates another open cursor in the databse rather than reusing the previous one. A work around I discovered by reading about REF CURSORS and I use in JDBC is as follows:
    Assuming a previously prepared PreparedStatement pstmt and a ResultSet rset-
    while (rset.next()) {
    rset.close();
    // This line closes the cursor in the database
    // but does not require you to re-prepare the
    // PreparedStatement. Don't ask me why--ask the
    // Oracle API guys.
    rset.getStatement().close();
    // make ready for GC
    rset = null;

  • XSU: Nested Collections?

    Does anyone know of a way to get around Oracle's limitation on nested collections?
    I have been using XSU to present XML to our Java application layer using objects and object views. Casting multisets works fine for repeating elements as long as the elements themselves don't contain repeating elements. I have been able to get around this with nested cursors, but I am not sure that XSU was designed to work this way. I get a nasty error if any of the cursors return an empty set.
    Example:
    SELECT
    company_name,
    CURSOR(SELECT
    dept_name,
    CURSOR(SELECT
    group_name
    FROM group_table g
    WHERE g.dept_id = d.dept_id) AS "GROUPS"
    FROM
    dept_table d
    WHERE
    d.company_id = c.company_id) AS "DEPARTMENTS"
    FROM company_table c
    If any of the above cursors returns an empty set then I get the following error:
    oracle.xml.sql.OracleXMLSQLException: Closed Statement: oracle.jdbc.oci8.OCIDBStatement@18f375
    Anyone gotten around this another way?

    Hi Christopher,
    I posted a similar question before. I even don't know how to create such a table to store XML data.
    Like your example
    <company>
    <dept>
    <group>
    <emp>
    </emp>
    </group>
    <group>
    </group>
    </dept>
    <dept>
    </dept>
    </company>
    Do you know how to create a table to store this kind of xml data with several hierarchical levels?
    null

  • Cursor Declaration

    I am trying to declare a cursor in a stored procedure using the following sql:
         CURSOR conversionCursor is select customer_number, company_id , buyer_id
         from hpsiuser.conversion_master natural join
         (select distinct mfg_code, customer_number
                                                 from hpsiuser.vendor_info, invoice_h
                                                 where vendor_id = vendorID);
    I get the following errors:
    Line # = 6 Column # = 29 Error Text = PL/SQL: SQL Statement ignored
    Line # = 6 Column # = 9 Error Text = PLS-00341: declaration of cursor 'CONVERSIONCURSOR' is incomplete or malformed
    Line # = 7 Column # = 43 Error Text = PL/SQL: ORA-06552: PL/SQL: Compilation unit analysis terminated ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformed
    My assumption is that it is having a problem with the join yet it works as a stand alone select statement.
    Any insight would be appreciated.
    Jon King

    CURSOR Expressions
    A CURSOR expression returns a nested cursor. This form of expression is equivalent to the PL/SQL REF CURSOR and can be passed as a REF CURSOR argument to a function.
    cursor_expression::=
    Text description of cursor_expression
    A nested cursor is implicitly opened when the cursor expression is evaluated. For example, if the cursor expression appears in a SELECT list, a nested cursor will be opened for each row fetched by the query. The nested cursor is closed only when:
    The nested cursor is explicitly closed by the user
    The parent cursor is reexecuted
    The parent cursor is closed
    The parent cursor is cancelled
    An error arises during fetch on one of its parent cursors (it is closed as part of the clean-up)
    Restrictions on CURSOR Expressions
    If the enclosing statement is not a SELECT statement, nested cursors can appear only as REF CURSOR arguments of a procedure.
    If the enclosing statement is a SELECT statement, nested cursors can also appear in the outermost SELECT list of the query specification, or in the outermost SELECT list of another nested cursor.
    Nested cursors cannot appear in views.
    You cannot perform BIND and EXECUTE operations on nested cursors.
    http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/expressions6a.htm#1035109
    Joel P�rez

  • Ref Cursor

    Hi,
    If anybody know how to execute function which has ref cursor type.
    Can I call that function in my select statement in query.
    Function is using week ref cursor type and id as IN parameter.
    Thans for you help in advance.

    You can use a function returning a ref cursor in SQL, the output is nested cursor though.
    SQL> create or replace function f
      2  return sys_refcursor
      3  as
      4    c sys_refcursor;
      5  begin
      6    open c for
      7      select * from emp where deptno = 10;
      8    return c;
      9  end;
    10  /
    Function created.
    SQL> select f from dual;
    F
    CURSOR STATEMENT : 1
    CURSOR STATEMENT : 1
    EMPNO ENAME      JOB          MGR HIREDATE      SAL   COMM DEPTNO
      7782 CLARK      MANAGER     7839 06-09-1981   2450            10
      7839 KING       PRESIDENT        11-17-1981   5000            10
      7934 MILLER     CLERK       7782 01-23-1982   1300            10
    SQL>

Maybe you are looking for