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. -
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,
BradIt 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,
wfOPEN 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 CummingsHere 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,
BobI 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 -
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 KingCURSOR 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 -
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
-
Why is my iphone does not accept my apple ID when entered in itunes and apps in settings?
-
HP Network Printer + windows 7 64bit
Hi I have a PC which I am using as a Printer Server. I have install 2 HP printers on it. One Colour(Clolor Laserjet Cp1515n) and other Black white (LaserJet 2300n). I am also running an autologin script on my main server which installc and connect my
-
How to use Print Control in Print List.
Please any body can explain me how to use print control when creating Print list? Thanks in advance.
-
Application failed codesign verification. The signature was invalid? Please help
Hi App developers Has anyone got a solution to this error when using Application uploader to ituneconnect? Application failed codesign verification. The signature was invalid, or it was not signed with an Apple submission certificate. I've created ne
-
When I try to cut and paste my resume' into an online job website it will not highlight, ( select all), I can click and drag it into the empty box but then it becomes an attachment. What am I doing wrong? Help!