ROWNUM question
So I have a SQL query in which I look at the ROWNUM and then perform formatting based on the row number. For example all rows under 15 show up with a highlighted column of blue, 16-30 show up red, etc. I want all of the rows from the blue group together and so on. I had an order by clause on the query of rownum but this wasn't working as expected as the returned results were always different for each user. I then tried to change the order by to sort by the primary key but then the highlighted rows aren't all together. Isn't the ROWNUM supposed to be read after the where clause? Here is my query below any ideas on how to get it functioning correctly.
select
(case when ROWNUM <= 15 then '<div align="center" style="background-color: #FFDAC1; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 1' || ' </div>'
when ROWNUM > 15 and ROWNUM <= '30' then '<div align="center" style="background-color: #C0C0FF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 2' || ' </div>'
when ROWNUM > 30 and ROWNUM <= 45 then '<div align="center" style="background-color: #DDFFDD; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 3' || ' </div>'
when ROWNUM >45 and ROWNUM <= 60 then '<div align="center" style="background-color: #FFFCC0; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 4' || ' </div>'
when ROWNUM > 60 and ROWNUM <= 75 then '<div align="center" style="background-color: #FAD8DF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 5' || ' </div>'
when ROWNUM > 75 and ROWNUM <= 90 then '<div align="center" style="background-color: #FFDAC1; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 6' || ' </div>'
when ROWNUM > 90 and ROWNUM <= 105 then '<div align="center" style="background-color: #C0C0FF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 7' || ' </div>'
when ROWNUM > 105 and ROWNUM <= 120 then '<div align="center" style="background-color: #DDFFDD; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 8' || ' </div>'
when ROWNUM > 120 and ROWNUM <= 135 then '<div align="center" style="background-color: #FFFCC0; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 9' || ' </div>'
when ROWNUM > 135 and ROWNUM <= 150 then '<div align="center" style="background-color: #FAD8DF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 10' || ' </div>'
when ROWNUM > 150 then '<div align="center" style="background-color: #e6e6e6; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 11' || ' </div>'END) row_1,
"SCHEDULE_ID",
"SCHEDULE_ID" SCHEDULE_ID_DISPLAY,
"CALL_DATE",
"CALL_IDENTIFIER",
"CALL_NAME",
"PRIMARY_PHONE",
"ALTERNATE_PHONE",
"NOTE",
"CSR_ID",
"COMPLETED",
"CALLBACK_DATE",
"CALLBACK_TIME",
RESCHEDULE_DATE,
RESCHEDULE_TIME,
CSR_NOTE,
SPREADSHEET_ID,
(case when PRIORITY = 'Y' then '<div align="center" style="background-color: #1073AA; font-weight: bold; color: #ffffff;"> ' || priority || ' </div>' END) priority,
call_completed_time
from "#OWNER#"."UID_CSR_SCHEDULE"
where trunc(sysdate)|| ' ' || :P9_TIME = upper(to_char(callback_date,'dd-mon-yy AM')) and (callback_cancelled is null or callback_cancelled != 'Y') and call_identifier is not null
order by ROWNUM
Thank you for your help...I will look at rewriting the case using the width once I get the return sequence correct. I have changed my query to below and it still doesn't seem to work...I must be doing something wrong! If I put an order by my_rownum then all the blocks are together but not in sequential order. If I set an order by clause of the id then the ids are sequential but the blocks are incorrect. I thought I had understood the previous replies and I read through the links but not sure what I am missing.
select
(case when MY_ROWNUM <= 15 then '<div align="center" style="background-color: #FFDAC1; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 1' || ' </div>'
when MY_ROWNUM > 15 and MY_ROWNUM <= 30 then '<div align="center" style="background-color: #C0C0FF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 2' || ' </div>'
when MY_ROWNUM > 30 and MY_ROWNUM <= 45 then '<div align="center" style="background-color: #DDFFDD; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 3' || ' </div>'
when MY_ROWNUM >45 and MY_ROWNUM <= 60 then '<div align="center" style="background-color: #FFFCC0; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 4' || ' </div>'
when MY_ROWNUM > 60 and MY_ROWNUM <= 75 then '<div align="center" style="background-color: #FAD8DF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 5' || ' </div>'
when MY_ROWNUM > 75 and MY_ROWNUM <= 90 then '<div align="center" style="background-color: #FFDAC1; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 6' || ' </div>'
when MY_ROWNUM > 90 and MY_ROWNUM <= 105 then '<div align="center" style="background-color: #C0C0FF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 7' || ' </div>'
when MY_ROWNUM > 105 and MY_ROWNUM <= 120 then '<div align="center" style="background-color: #DDFFDD; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 8' || ' </div>'
when MY_ROWNUM > 120 and MY_ROWNUM <= 135 then '<div align="center" style="background-color: #FFFCC0; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 9' || ' </div>'
when MY_ROWNUM > 135 and MY_ROWNUM <= 150 then '<div align="center" style="background-color: #FAD8DF; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 10' || ' </div>'
when MY_ROWNUM > 150 then '<div align="center" style="background-color: #e6e6e6; font-weight: bold; color: #OOOOOO;"> ' || 'BLOCK 11' || ' </div>'END) row_1,
"SCHEDULE_ID",
"SCHEDULE_ID" SCHEDULE_ID_DISPLAY,
"CALL_DATE",
"CALL_IDENTIFIER",
"CALL_NAME",
"PRIMARY_PHONE",
"ALTERNATE_PHONE",
"NOTE",
"CSR_ID",
"COMPLETED",
"CALLBACK_DATE",
"CALLBACK_TIME",
RESCHEDULE_DATE,
RESCHEDULE_TIME,
CSR_NOTE,
SPREADSHEET_ID,
(case when PRIORITY = 'Y' then '<div align="center" style="background-color: #1073AA; font-weight: bold; color: #ffffff;"> ' || priority || ' </div>' END) priority,
call_completed_time
from (SELECT ROWNUM MY_ROWNUM, SCHEDULE_ID, CALL_DATE, CALL_IDENTIFIER, CALL_NAME, PRIMARY_PHONE, ALTERNATE_PHONE, NOTE, CSR_ID, COMPLETED, CALLBACK_DATE, CALLBACK_TIME, RESCHEDULE_DATE, RESCHEDULE_TIME, CSR_NOTE, SPREADSHEET_ID, PRIORITY, CALL_COMPLETED_TIME FROM UID_CSR_SCHEDULE WHERE trunc(sysdate)|| ' ' || 'PM' = upper(to_char(callback_date,'dd-mon-yy AM')) and (callback_cancelled is null or callback_cancelled != 'Y') and call_identifier is not null ORDER BY SCHEDULE_ID )
order by MY_ROWNUM
Similar Messages
-
I am using JDeveloper 11.1.1.3.0 and I have a question about the range paging access mode and I went through some docs but couldn't get myself to answer all the questions I have.
1. In the VO's I set the Access Mode to Range Paging and set the Range Size to 25 but I only have (at this time) 19 rows. But in the logs, I notice:
"<OracleSQLBuilderImpl><bindRangePagingParams> [2540] setting rownum query between (0, 28)"
which doesn't make sense. Firstly, 0-28 is not a 25 row range and secondly, why is the SQL even accessing anything outside the range of 25 when there are only 19 rows for the VO?
2. Also, I have two buttons on the page (page fragment #1) which performs operations (add a new row, version an existing row) by having the user go to a different page fragment (page fragment #2). After the user submits the info and returns to the original page (page fragment #1), I see this message in a pop-up:
"Cannot navigate with unposted rows in a RangePaging RowSet"
which, although not an error, doesn't make sense because the info was saved in the DB.
Hope my questions make sense.I don't have the url reference handy for the "official" word, but I recall that jdev overfetches 3 records in range paging mode.
It's not known that there are only 19 records until the first batch is fetched, which is why you see 0-28.
Just noticed the second question - no comment on that one, unfortunately ;)
John -
Question about order by and rownum and subqueries.
Can you explain why test 4 below results as it results- with returning no rows?
Identificator "PKG_INTRA_CUSTOMER_SEARCH.NAME" is a package function, which returns value from a variable declared in package body, the function returns value 'e%'.
Please note that tests 1-3 all returned data, but test 4 didn't. Why? My porpouse is that test 4 would also return data.
1. Query without "rownum" and with "Order by" returns 2 records:
select q.*--, rownum
,PKG_INTRA_CUSTOMER_SEARCH.NAME
from
select c.ID,
c.NAME,
c.CODE
from V_CUSTOMER c
where 1=1 and lower(c.NAME) like PKG_INTRA_CUSTOMER_SEARCH.NAME
order by c.NAME, c.ID
) q
10020 Ees Nimi 37810010237 e%
10040 ewewrwe werwerwer e%2. Query with "rownum" and without "Order by" returns 2 records:
select q.*, rownum
,PKG_INTRA_CUSTOMER_SEARCH.NAME
from
select c.ID,
c.NAME,
c.CODE
from V_CUSTOMER c
where 1=1 and lower(c.NAME) like PKG_INTRA_CUSTOMER_SEARCH.NAME
--order by c.NAME, c.ID
) q
10020 Ees Nimi 37810010237 e%
10040 ewewrwe werwerwer e%3.Query without "rownum" and with "Order by" returns 2 records:
select q.*--, rownum
,PKG_INTRA_CUSTOMER_SEARCH.NAME
from
select c.ID,
c.NAME,
c.CODE
from V_CUSTOMER c
where 1=1 and lower(c.NAME) like PKG_INTRA_CUSTOMER_SEARCH.NAME
order by c.NAME, c.ID
) q
10020 Ees Nimi 37810010237 e%
10040 ewewrwe werwerwer e% 4. Query with "rownum" and with "Order by" returns 0 records:
select q.*, rownum
,PKG_INTRA_CUSTOMER_SEARCH.NAME
from
select c.ID,
c.NAME,
c.CODE
from V_CUSTOMER c
where 1=1 and lower(c.NAME) like PKG_INTRA_CUSTOMER_SEARCH.NAME
order by c.NAME, c.ID
) qHi,
please reproduce the question in your test database with script below.
My general question is that wht Test5 below returns only 1 row, but Test5 returns 3 rows.
The difference between those two tests is only that one has "order by" clause, the other doesn't have.
I need the "order by" clause to stay, but seems like it is not allowed.
CREATE OR REPLACE
PACKAGE PACKAGE1 AS
function NAME return varchar2;
END PACKAGE1;
CREATE OR REPLACE
PACKAGE body PACKAGE1 AS
function NAME return varchar2
is
begin
return 'e%';
end NAME;
END PACKAGE1;
select PACKAGE1.name from dual--e%
create table Tbl AS
(SELECT 'e2b' Col1, 'A' Col2, 'AA' Col3 FROM dual
UNION
SELECT 'e3b', 'B','BB' FROM dual
--Test5:
select q.*, rownum pos, PACKAGE1.name f
from
select c.col1,
c.col2,
c.col3
from Tbl c
where 1=1 and lower(c.col1) like PACKAGE1.name
order by c.col2, c.col1
) q
union all
select '111' , '111' , '111' , 0 pos, PACKAGE1.name f from dual --return 1 row
--Test6
select q.*, rownum pos, PACKAGE1.name f
from
select c.col1,
c.col2,
c.col3
from Tbl c
where 1=1 and lower(c.col1) like PACKAGE1.name
--order by c.col2, c.col1
) q
union all
select '111' , '111' , '111' , 0 pos, PACKAGE1.name f from dual --return 3 rowsEdited by: CharlesRoos on Feb 17, 2010 5:30 AM -
I am trying to create line numbers. I thought I could use rownum to do this but the information
needed to be sorted.
Once I sorted it it through line numbers off.
How can I create either a counter or sort the information and use rownum.
HowardROWNUM is applied before the ORDER BY. You could nest your query,i.e.
SELECT a.*, rownum
FROM (<<your query with ORDER BY here>>) aor you could use the analytic function row_number in your query, i.e.
SELECT list_of_columns
row_number() over (order by some_column)
FROM your_table
WHERE your_conditions
ORDER BY same_column_list_as_in_row_number_functionJustin -
why "select ####### from ###### where rownum <=###" can work,but
"select ####### from ###### where rownum >###"
and
"select ####### from ###### where rownum =###" can not work
nullFollow the following logic to fullfil ur requiremnet.
create table tt as select rownum r,empno,ename from emp;
Table created.
SQL> select * from tt;
R EMPNO ENAME
1 7369 SMITH
2 7499 ALLEN
3 7521 WARD
4 7566 JONES
5 7654 MARTIN
6 7698 BLAKE
7 7782 CLARK
8 7788 SCOTT
9 7839 KING
10 7844 TURNER
11 7876 ADAMS
R EMPNO ENAME
12 7900 JAMES
13 7902 FORD
14 7934 MILLER
14 rows selected.
SQL> select * from tt where r=7;
R EMPNO ENAME
7 7782 CLARK
SQL> select * from tt where r>7
R EMPNO ENAME
8 7788 SCOTT
9 7839 KING
10 7844 TURNER
11 7876 ADAMS
12 7900 JAMES
13 7902 FORD
14 7934 MILLER
7 rows selected.
null -
How would I write an if and else statement to indicate if the number of records that are returned by the select statement is more than 1, do this.
Example:
declare name employee.name%type;
begin
select name from employee
where salary = v_salary;
if rownum > 1 then
raise e_more;
endif;
exception
when e_more then
commit;
end;Hi Sooraj,
What I am trying to say is..
Take your code :(Here Your code is used as a procedure.Anyhow your code is missing a lot of ";")
SQL> create or replace procedure p1
2 is
3 --Your code
4 v_count NUMBER;
5 v_name VARCHAR2(100);
6 BEGIN
7 SELECT ename INTO V_name FROM emp;
8 v_count:= SQL%ROWCOUNT;
9 IF(v_count=1) THEN
10 dbms_output.put_line(v_count);
11 END IF;
12 END;
13 /
Procedure created.
--Now run it for EMP table with one row
SQL> delete from emp where empno != 7521;
13 rows deleted.
SQL> exec p1;
1
PL/SQL procedure successfully completed.
--Runs fine.But for EMP table with more than one rows..
SQL> roll
Rollback complete.
SQL> exec p1;
BEGIN p1; END;
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SCOTT.P1", line 7
ORA-06512: at line 1
--And for EMP table with no rows..
SQL> delete from emp;
14 rows deleted.
SQL> exec p1;
BEGIN p1; END;
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "SCOTT.P1", line 7
ORA-06512: at line 1
So, My point is you have to make use of exception handling here.. -
A question about the impact of SQL*PLUS SERVEROUTPUT option on v$sql
Hello everybody,
SQL> SELECT * FROM v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL>
OS : Fedora Core 17 (X86_64) Kernel 3.6.6-1.fc17.x86_64I would like to ask a question about the SQL*Plus SET SERVEROUTPUT ON/OFF option and its impact on queries on views such as v$sql and v$session. Here is the problem
Actually I define three variables in SQL*Plus in order to store sid, serial# and prev_sql_id columns from v$session in order to be able to use them later, several times in different other queries, while I'm still working in the current session.
So, here is how I proceed
SET SERVEROUTPUT ON; -- I often activate this option as the first line of almost all of my SQL-PL/SQL script files
SET SQLBLANKLINES ON;
VARIABLE mysid NUMBER
VARIABLE myserial# NUMBER;
VARIABLE saved_sql_id VARCHAR2(13);
-- So first I store sid and serial# for the current session
BEGIN
SELECT sid, serial# INTO :mysid, :myserial#
FROM v$session
WHERE audsid = SYS_CONTEXT('UserEnv', 'SessionId');
END;
PL/SQL procedure successfully completed.
-- Just check to see the result
SQL> SELECT :mysid, :myserial# FROM DUAL;
:MYSID :MYSERIAL#
129 1067
SQL> Now, let's say that I want to run the following query as the last SQL statement run within my current session
SELECT * FROM employees WHERE salary >= 2800 AND ROWNUM <= 10;According to Oracle® Database Reference 11g Release 2 (11.2) description for v$session
http://docs.oracle.com/cd/E11882_01/server.112/e25513/dynviews_3016.htm#REFRN30223]
the column prev_sql_id includes the sql_id of the last sql statement executed for the given sid and serial# which in the case of my example, it will be the above mentioned SELECT query on the employees table. As a result, right after the SELECT statement on the employees table I run the following
BEGIN
SELECT prev_sql_id INTO :saved_sql_id
FROM v$session
WHERE sid = :mysid AND serial# = :myserial#;
END;
PL/SQL procedure successfully completed.
SQL> SELECT :saved_sql_id FROM DUAL;
:SAVED_SQL_ID
9babjv8yq8ru3
SQL> Having the value of sql_id, I'm supposed to find all information about cursor(s) for my SELECT statement and also its sql_text value in v$sql. Yet here is what I get when I query v$sql upon the stored sql_id
SELECT child_number, sql_id, sql_text
FROM v$sql
WHERE sql_id = :saved_sql_id;
CHILD_NUMBER SQL_ID SQL_TEXT
0 9babjv8yq8ru3 BEGIN DBMS_OUTPUT.GET_LINES(:LINES, :NUMLINES); END;Therefore instead of
SELECT * FROM employees WHERE salary >= 2800 AND ROWNUM <= 10;for the value of sql_text I get the following value
BEGIN DBMS_OUTPUT.GET_LINES(:LINES, :NUMLINES);Which is not of course what I was expecting to find in v$sql for the given sql_id.
After a bit googling I found the following thread on the OTN forum where it had been suggested (well I think maybe not exactly for the same problem) to turn off SERVEROUTPUT.
Problem with dbms_xplan.display_cursor
This was precisely what I did
SET SERVEROUTPUT OFFafter that I repeated the whole procedure and this time everything worked pretty well as expected. I checked SQL*Plus documentation for SERVEROUTPUT
and also v$session page, yet I didn't find anything indicating that SERVEROUTPUT should be switched off whenever views such as v$sql, v$session
are queired. I don't really understand the link in terms of impact that one can have on the other or better to say rather, why there is an impact
Could anyone kindly make some clarification?
thanks in advance,
Regards,
Dariyoosh>
and also v$session page, yet I didn't find anything indicating that SERVEROUTPUT should be switched off whenever views such as v$sql, v$session
are queired. I don't really understand the link in terms of impact that one can have on the other or better to say rather, why there is an impact
Hi Dariyoosh,
SET SERVEROUTPUT ON has the effect of executing dbms_output.get_lines after each and every statement. Not only related to system view.
Here below what Tom Kyte is explaining in this page:
Now, sqlplus sees this functionality and says "hey, would not it be nice for me to dump this buffer to screen for the user?". So, they added the SQLPlus command "set serveroutput on" which does two things
1) it tells SQLPLUS you would like it <b>to execute dbms_output.get_lines after each and every statement</b>. You would like it to do this network rounding after each call. You would like this extra overhead to take place (think of an install script with hundreds/thousands of statements to be executed -- perhaps, just perhaps you don't want this extra call after every call)
2) SQLPLUS automatically calls the dbms_output API "enable" to turn on the buffering that happens in the package.Regards.
Al -
Simple Query Question - How do I return the Last 3 records of a Table?
Question.
For example, I have a table that has 50 records.
How do I, specify in SQL to only return the last 3 records of the table.
Select a.* from table a where ????I was just trying to show an example to a friend on
how something like this would work and if it was even possible. But it won't work. Here's a simple example:
SQL> create table emp
2 (id)
3 as
4 select object_id
5 from all_objects
6 order by object_id;
Table created.
SQL> select *
2 from (select rownum rn
3 ,b.*
4 from emp b)
5 where rn > ( select (max(rownum) - 3)
6 from emp)
7 ;
RN ID
40830 55891
40831 55892
40832 55893So far, so good. These are the "last 3" rows inserted. Now delete a bunch of rows and insert 3 new ones:
SQL> delete emp where id < 40000;
33423 rows deleted.
SQL> commit;
Commit complete.
SQL> insert into emp values (60000);
1 row created.
SQL> insert into emp values (60001);
1 row created.
SQL> insert into emp values (60002);
1 row created.
SQL> commit;
Commit complete.
SQL> select *
2 from (select rownum rn
3 ,b.*
4 from emp b)
5 where rn > ( select (max(rownum) - 3)
6 from emp)
7 ;
RN ID
7410 55891
7411 55892
7412 55893Here's the problem. Even though the "last 3 rows" are 60000 - 60002, I still get the same ones as the first query. -
XMLType column based on XML Schema: several questions
Hi,
I've a table on an oracle db version 10.1.0.4 where I stage the xml files containing orders created on a third party's system using BizTalk.
Although the storage I opted for is based on an XML Schema, defined by this third-party, I am facing big perfomance issues with files bigger than a few hundreds of kBs.
For instance, a 32Mb file takes more than 2 hours to be processed.
Now, after reading other threads in this forum and the documentation, my understanding of the problem is that the whole issue is with the correct indexing of the nested tables.
Here is my current XML Schema definition:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xdb:storeVarrayAsTable="true">
<xs:include schemaLocation="private/Types.xsd"/>
<xs:element name="PickData">
<xs:complexType xdb:maintainDOM="false">
<xs:sequence>
<xs:element name="ProdRun">
<xs:complexType xdb:maintainDOM="false">
<xs:sequence>
<xs:element name="Nr" type="xs:int"/>
<xs:element name="Date" type="string8"/>
<xs:element name="Final" type="xs:int"/>
<xs:element name="PickWave" maxOccurs="unbounded">
<xs:complexType xdb:maintainDOM="false">
<xs:sequence>
<xs:element name="Nr" type="string10"/>
<xs:element name="ProdLine" type="string2"/>
<xs:element name="TourSeq" type="xs:int"/>
<xs:element name="Tour" type="string20"/>
<xs:element name="Customer" maxOccurs="unbounded">
<xs:complexType xdb:maintainDOM="false">
<xs:sequence>
<xs:element name="Seq" type="string20"/>
<xs:element name="Cust" type="string10"/>
<xs:element name="Mod" type="string30"/>
<xs:element name="Tod" type="string30"/>
<xs:element name="InvOrder" maxOccurs="unbounded">
<xs:complexType xdb:maintainDOM="false">
<xs:sequence>
<xs:element name="Nr" type="string20"/>
<xs:element name="Item" type="string20"/>
<xs:element name="Qty" type="xs:int"/>
<xs:element name="Priority" type="xs:int"/>
<xs:element name="Reordering" type="xs:int"/>
<xs:element name="DelDate" type="string8"/>
<xs:element name="HlOrder" type="string20"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="InvOrderKey">
<xs:selector xpath="InvOrder"/>
<xs:field xpath="Nr"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="CustomerKey">
<xs:selector xpath="Customer"/>
<xs:field xpath="Seq"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="PickWaveKey">
<xs:selector xpath="PickWave"/>
<xs:field xpath="Nr"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="ProdRunKey">
<xs:selector xpath="ProdRun"/>
<xs:field xpath="Nr"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Here is the included sub-schema:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="string2">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="2"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string5">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="5"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string6">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="6"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string8">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="8"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string10">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string15">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="15"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string20">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="20"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string30">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string40">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="40"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string50">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="string250">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="250"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
The statement for creating my table is
CREATE TABLE "XML_ORDERS"
("ID" NUMBER(7,0) NOT NULL ENABLE,
"XMLFILE" "SYS"."XMLTYPE" ,
"INSERTED" DATE DEFAULT sysdate,
CONSTRAINT "XML_ORDERS_PK" PRIMARY KEY ("ID") USING INDEX ENABLE
) XMLTYPE COLUMN XMLFILE STORE AS OBJECT RELATIONAL
XMLSCHEMA "private/PickData.xsd" ELEMENT "PickData"
Here is a simple instance document:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PickData xsi:noNamespaceSchemaLocation="private/PickData.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ProdRun>
<Nr>5</Nr>
<Date>15112005</Date>
<Final>1</Final>
<PickWave>
<Nr>IPW0000017</Nr>
<ProdLine>01</ProdLine>
<TourSeq>1</TourSeq>
<Tour>00000043_078</Tour>
<Customer>
<Seq>5</Seq>
<Cust>100000006</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000457</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000742</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000459</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000742</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>6</Seq>
<Cust>100000013</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000461</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000743</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000463</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000743</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>2</Seq>
<Cust>100000114</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000465</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000744</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000467</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000744</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>3</Seq>
<Cust>100000140</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000469</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000745</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000471</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000745</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>7</Seq>
<Cust>100000143</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000473</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000746</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000475</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000746</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>8</Seq>
<Cust>100000145</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000477</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000747</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000479</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000747</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>9</Seq>
<Cust>100000146</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000481</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>0</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000748</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000483</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000748</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>4</Seq>
<Cust>100000147</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000485</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>0</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000750</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000487</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000750</HlOrder>
</InvOrder>
</Customer>
<Customer>
<Seq>10</Seq>
<Cust>100000148</Cust>
<Mod>FO</Mod>
<Tod>DDU</Tod>
<InvOrder>
<Nr>IIO0000489</Nr>
<Item>100000036</Item>
<Qty>20</Qty>
<Priority>0</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000751</HlOrder>
</InvOrder>
<InvOrder>
<Nr>IIO0000491</Nr>
<Item>100000045</Item>
<Qty>20</Qty>
<Priority>1</Priority>
<Reordering>0</Reordering>
<DelDate>15112005</DelDate>
<HlOrder>CSO000751</HlOrder>
</InvOrder>
</Customer>
</PickWave>
</ProdRun>
</PickData>
When I registered the XMLSchema, the following types and tables were automatically created and you can see the hierarchy below:
(by the way, I could not find any xdb_utilities.printNestedTables mentioned elsewhere)
XML_ORDERS
|_PickData381_T
|___ProdRun382_T
|_____PickWave388_COLL
|_______PickWave383_T
|_________Customer387_COLL
|___________Customer384_T
|_____________InvOrder386_COLL
These objects are then used in the following nested tables:
TABLE_NAME TABLE_TYPE_NAME PARENT_TABLE_NAME PARENT_TABLE_COLUMN
SYS_NTaK/5zar5S0WitSsgu6OKPQ== PickWave388_COLL PickData389_TAB "XMLDATA"."ProdRun"."PickWave"
SYS_NTf6QvwVm8SFKz+K/YYWq+WQ== Item408_COLL ProdData409_TAB "XMLDATA"."Item"
SYS_NTtu05ilrRQqmuEN4k+07VDA== Customer402_COLL OutboundParty403_TAB "XMLDATA"."Customer"
SYS_NTK6fhWq5uTJ+vKcgBpNm1Fg== InvOrder386_COLL SYS_NTIIzv7bkXQSSS43igtfi5eg== InvOrder
SYS_NTIIzv7bkXQSSS43igtfi5eg== Customer387_COLL SYS_NTaK/5zar5S0WitSsgu6OKPQ== Customer
I enabled sql tracing and I got the following TKPROF output
INSERT INTO IMP_ORDERS (PICK_INVORDERNR, PICK_ITEM, PICK_QTY, PICK_PRIORITY,
PICK_REORDERING, PICK_HLORDER, PICK_DELDATE, PICK_CUST, PICK_MOD, PICK_TOD,
PICK_SEQ, PICK_PICKWAVENR, PICK_PICKWAVEPRODLINE, PICK_PICKWAVETOUR,
PICK_PICKWAVETOURSEQ, PICK_ORDKEY, PICK_RUNKEY) SELECT INVORDERNR, ITEM,
QTY, PRIORITY, REORDERING, HLORDER, DELDATE, CUST, MOD, TOD, SEQ,
PICKWAVENR, PICKWAVEPRODLINE, PICKWAVETOUR, PICKWAVETOURSEQ, ROWNUM AS
PICK_ORDKEY, PRODRUNID FROM (SELECT /*+ cardinality(g 15)*/
EXTRACTVALUE(VALUE(G), '/InvOrder/Nr') AS INVORDERNR, EXTRACTVALUE(VALUE(G),
'/InvOrder/Item') AS ITEM, EXTRACTVALUE(VALUE(G), '/InvOrder/Qty') AS QTY,
EXTRACTVALUE(VALUE(G), '/InvOrder/Priority') AS PRIORITY,
EXTRACTVALUE(VALUE(G), '/InvOrder/Reordering') AS REORDERING,
EXTRACTVALUE(VALUE(G), '/InvOrder/HlOrder') AS HLORDER,
TO_DATE(EXTRACTVALUE(VALUE(G), '/InvOrder/DelDate'),'DDMMYYYY') AS DELDATE,
F.CUST, F.MOD, F.TOD, F.SEQ, F.PICKWAVENR, F.PICKWAVEPRODLINE,
F.PICKWAVETOUR, F.PICKWAVETOURSEQ, F.PRODRUNNR, F.PRODRUNDATE,
F.PRODRUNFINAL, F.PRODRUNID FROM (SELECT /*+ cardinality(e 60)*/VALUE(E) AS
CUSTOMERNODE, EXTRACTVALUE(VALUE(E), '/Customer/Cust') AS CUST,
EXTRACTVALUE(VALUE(E), '/Customer/Mod') AS MOD, EXTRACTVALUE(VALUE(E),
'/Customer/Tod') AS TOD, TO_NUMBER(EXTRACTVALUE(VALUE(E), '/Customer/Seq'))
AS SEQ, D.PICKWAVENR, D.PICKWAVEPRODLINE, D.PICKWAVETOUR, D.PICKWAVETOURSEQ,
D.PRODRUNNR, D.PRODRUNDATE, D.PRODRUNFINAL, D.PRODRUNID FROM (SELECT /*+
cardinality(c 100)*/VALUE(C) AS PICKWAVENODE, EXTRACTVALUE(VALUE(C),
'/PickWave/Nr') AS PICKWAVENR, TO_NUMBER(EXTRACTVALUE(VALUE(C),
'/PickWave/ProdLine')) AS PICKWAVEPRODLINE, EXTRACTVALUE(VALUE(C),
'/PickWave/Tour') AS PICKWAVETOUR, TO_NUMBER(EXTRACTVALUE(VALUE(C),
'/PickWave/TourSeq')) AS PICKWAVETOURSEQ, A.PRODRUNNR, A.PRODRUNDATE,
A.PRODRUNFINAL, A.PRODRUNID FROM (SELECT /*+ cardinality(b 1)*/VALUE(B) AS
PRODRUNNODE, EXTRACTVALUE(VALUE(B), '/ProdRun/Nr') AS PRODRUNNR,
TO_DATE(EXTRACTVALUE(VALUE(B), '/ProdRun/Date'),'DDMMYYYY') AS PRODRUNDATE,
EXTRACTVALUE(VALUE(B), '/ProdRun/Final') AS PRODRUNFINAL, X.ID PRODRUNID
FROM XML_ORDERS X, TABLE(XMLSEQUENCE(EXTRACT(X.XMLFILE,'/PickData/ProdRun'))
) B WHERE X.ID = :B1 ) A, TABLE(XMLSEQUENCE(EXTRACT(A.PRODRUNNODE,
'/ProdRun/PickWave'))) C ) D, TABLE(XMLSEQUENCE(EXTRACT(D.PICKWAVENODE,
'/PickWave/Customer'))) E ) F, TABLE(XMLSEQUENCE(EXTRACT(F.CUSTOMERNODE,
'/Customer/InvOrder'))) G ORDER BY PICKWAVEPRODLINE, PICKWAVETOURSEQ,
PICKWAVENR, SEQ )
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 4324.09 9994.65 0 57193 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 2 4324.09 9994.65 0 57193 0 0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 68 (recursive depth: 1)
Rows Row Source Operation
0 COUNT (cr=0 pr=0 pw=0 time=180 us)
0 VIEW (cr=0 pr=0 pw=0 time=166 us)
0 SORT ORDER BY (cr=0 pr=0 pw=0 time=152 us)
40866 NESTED LOOPS (cr=54973 pr=0 pw=0 time=31065606 us)
1363 NESTED LOOPS (cr=54937 pr=0 pw=0 time=11037183 us)
1 NESTED LOOPS (cr=54889 pr=0 pw=0 time=10145883 us)
1 NESTED LOOPS (cr=54841 pr=0 pw=0 time=9799012 us)
1 TABLE ACCESS BY INDEX ROWID XML_ORDERS (cr=2 pr=0 pw=0 time=222 us)
1 INDEX UNIQUE SCAN XML_ORDERS_PK (cr=1 pr=0 pw=0 time=126 us)(object id 58551)
1 COLLECTION ITERATOR PICKLER FETCH (cr=54839 pr=0 pw=0 time=9798748 us)
1 COLLECTION ITERATOR PICKLER FETCH (cr=48 pr=0 pw=0 time=346818 us)
1363 COLLECTION ITERATOR PICKLER FETCH (cr=48 pr=0 pw=0 time=870830 us)
40866 COLLECTION ITERATOR PICKLER FETCH (cr=36 pr=0 pw=0 time=18739302 us)
Note that I cancelled this operation before it was over so I imagine that these figures refer to the statistics as of the time when the operation was interrupted.
So, here are finally my questions.
In order to create the constraints on the nested tables as shown in other threads, do I need to drop the existing xml_orders table and ancillary object types and recreate them or is there a way to add such constraints using the existing system generated object names?
Secondly, the xml_orders table may contain severale documents, not just one and his current primary key is the column ID. So, in order to uniquely identify the deepest element in the xml document, I need first to select the relevant document by means of the id column.
Would it be better to create the indexes containing this id column together with the nested_table_id and array_index?
Thanks for you help.
Flavio
PS: I wrote a 10 lines xsl transformation that I passed on to Saxon together with the 32Mb file. It took less than 1 minute to produce a flat file that was loaded almost instantly by SQL*Loader. So, what I am looking for is a procedure loading this stuff in less than 2 minutes or possibly less.Does the following help
SQL*Plus: Release 10.2.0.1.0 - Production on Tue Dec 27 21:44:53 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> spool registerSchema_&4..log
SQL> set trimspool on
SQL> connect &1/&2
Connected.
SQL> --
SQL> declare
2 result boolean;
3 begin
4 result := dbms_xdb.createResource('/home/&1/xsd/&4',
5 bfilename(USER,'&4'),nls_charset_id('AL32UTF8'));
6 end;
7 /
old 4: result := dbms_xdb.createResource('/home/&1/xsd/&4',
new 4: result := dbms_xdb.createResource('/home/OTNTEST/xsd/GetaxTypes.xsd',
old 5: bfilename(USER,'&4'),nls_charset_id('AL32UTF8'));
new 5: bfilename(USER,'GetaxTypes.xsd'),nls_charset_id('AL32UTF8'));
PL/SQL procedure successfully completed.
SQL> commit
2 /
Commit complete.
SQL> alter session set events='31098 trace name context forever'
2 /
Session altered.
SQL> begin
2 dbms_xmlschema.registerSchema
3 (
4 schemaURL => '&3',
5 schemaDoc => xdbURIType('/home/&1/xsd/&4').getClob(),
6 local => TRUE,
7 genTypes => TRUE,
8 genBean => FALSE,
9 genTables => &5
10 );
11 end;
12 /
old 4: schemaURL => '&3',
new 4: schemaURL => 'private/GetaxTypes.xsd',
old 5: schemaDoc => xdbURIType('/home/&1/xsd/&4').getClob(),
new 5: schemaDoc => xdbURIType('/home/OTNTEST/xsd/GetaxTypes.xsd').getClob(),
old 9: genTables => &5
new 9: genTables => TRUE
PL/SQL procedure successfully completed.
SQL> quit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL*Plus: Release 10.2.0.1.0 - Production on Tue Dec 27 21:44:55 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> spool registerSchema_&4..log
SQL> set trimspool on
SQL> connect &1/&2
Connected.
SQL> --
SQL> declare
2 result boolean;
3 begin
4 result := dbms_xdb.createResource('/home/&1/xsd/&4',
5 bfilename(USER,'&4'),nls_charset_id('AL32UTF8'));
6 end;
7 /
old 4: result := dbms_xdb.createResource('/home/&1/xsd/&4',
new 4: result := dbms_xdb.createResource('/home/OTNTEST/xsd/PickData.xsd',
old 5: bfilename(USER,'&4'),nls_charset_id('AL32UTF8'));
new 5: bfilename(USER,'PickData.xsd'),nls_charset_id('AL32UTF8'));
PL/SQL procedure successfully completed.
SQL> commit
2 /
Commit complete.
SQL> alter session set events='31098 trace name context forever'
2 /
Session altered.
SQL> begin
2 dbms_xmlschema.registerSchema
3 (
4 schemaURL => '&3',
5 schemaDoc => xdbURIType('/home/&1/xsd/&4').getClob(),
6 local => TRUE,
7 genTypes => TRUE,
8 genBean => FALSE,
9 genTables => &5
10 );
11 end;
12 /
old 4: schemaURL => '&3',
new 4: schemaURL => 'private/PickData.xsd',
old 5: schemaDoc => xdbURIType('/home/&1/xsd/&4').getClob(),
new 5: schemaDoc => xdbURIType('/home/OTNTEST/xsd/PickData.xsd').getClob(),
old 9: genTables => &5
new 9: genTables => TRUE
PL/SQL procedure successfully completed.
SQL> quit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL*Plus: Release 10.2.0.1.0 - Production on Tue Dec 27 21:44:58 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> spool createTable.log
SQL> --
SQL> connect &1/&2
Connected.
SQL> --
SQL> CREATE TABLE "XML_ORDERS"
2 ("ID" NUMBER(7,0) NOT NULL ENABLE,
3 "XMLFILE" "SYS"."XMLTYPE" ,
4 "INSERTED" DATE DEFAULT sysdate,
5 CONSTRAINT "XML_ORDERS_PK" PRIMARY KEY ("ID") USING INDEX ENABLE
6 ) XMLTYPE COLUMN XMLFILE STORE AS OBJECT RELATIONAL
7 XMLSCHEMA "private/PickData.xsd"
8 ELEMENT "PickData"
9 VARRAY XMLFILE."XMLDATA"."ProdRun"."PickWave" STORE AS TABLE PickWave_TAB
10 (
11 ( primary key (nested_table_id, array_index)
12 ) organization index overflow
13 VARRAY "Customer" STORE AS TABLE Customer_TAB
14 (
15 (primary key (nested_table_id, array_index)
16 ) organization index overflow
17 VARRAY "InvOrder" STORE AS TABLE InvOrder_TAB
18 (
19 (primary key (nested_table_id, array_index)
20 ) organization index overflow
21 )
22 )
23 )
24 /
Table created.
SQL> quit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL*Plus: Release 10.2.0.1.0 - Production on Tue Dec 27 21:44:59 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> spool insertFile_&3..log
SQL> set trimspool on
SQL> connect &1/&2
Connected.
SQL> --
SQL> set timing on
SQL> set long 10000
SQL> --
SQL> insert into XML_ORDERS (ID, XMLFILE) values (&4, xmltype(bfilename(USER,'&3'),nls_charset_id('AL32UTF8')))
2 /
old 1: insert into XML_ORDERS (ID, XMLFILE) values (&4, xmltype(bfilename(USER,'&3'),nls_charset_id('AL32UTF8')))
new 1: insert into XML_ORDERS (ID, XMLFILE) values (10, xmltype(bfilename(USER,'testcase.xml'),nls_charset_id('AL32UT
8')))
1 row created.
Elapsed: 00:00:00.11
SQL> commit
2 /
Commit complete.
Elapsed: 00:00:00.01
SQL> quit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL*Plus: Release 10.2.0.1.0 - Production on Tue Dec 27 21:44:59 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> spool testcase.log
SQL> set trimspool on
SQL> connect &1/&2
Connected.
SQL> --
SQL> set timing on
SQL> set long 10000
SQL> set pages 0 lines 140
SQL> --
SQL> -- Testcase code here
SQL> --
SQL> set autotrace on explain
SQL> --
SQL> create or replace view PROD_RUN_VIEW
2 (
3 PRODRUNNODE,
4 PRODRUNNR,
5 PRODRUNDATE,
6 PRODRUNID,
7 PRODRUNFINAL
8 )
9 as
10 select EXTRACT(XMLFILE,'/PickData/ProdRun'),
11 EXTRACTVALUE(XMLFILE , '/PickData/ProdRun/Nr'),
12 TO_DATE(EXTRACTVALUE(XMLFILE, '/PickData/ProdRun/Date'),'DDMMYYYY'),
13 ID,
14 EXTRACTVALUE(XMLFILE,'/PickData/ProdRun/Final')
15 from XML_ORDERS
16 /
View created.
Elapsed: 00:00:00.09
SQL> create or replace view PICK_WAVE_VIEW
2 (
3 PICKWAVENODE,
4 PICKWAVENR,
5 PICKWAVEPRODLINE,
6 PICKWAVETOUR,
7 PICKWAVETOURSEQ,
8 PRODRUNNR,
9 PRODRUNDATE,
10 PRODRUNID,
11 PRODRUNFINAL
12 )
13 as
14 select value(PW),
15 extractValue(value(PW),'/PickWave/Nr'),
16 TO_NUMBER(EXTRACTVALUE(value(PW),'/PickWave/ProdLine')),
17 extractValue(value(PW),'/PickWave/Tour'),
18 TO_NUMBER(extractValue(value(PW),'/PickWave/TourSeq')),
19 PRODRUNNR,
20 PRODRUNDATE,
21 PRODRUNID,
22 PRODRUNFINAL
23 FROM PROD_RUN_VIEW, table(xmlsequence(extract(PRODRUNNODE,'/ProdRun/PickWave'))) PW
24 /
View created.
Elapsed: 00:00:00.09
SQL> create or replace view CUSTOMER_VIEW
2 (
3 CUSTOMERNODE,
4 CUST,
5 MOD,
6 TOD,
7 SEQ,
8 PICKWAVENR,
9 PICKWAVEPRODLINE,
10 PICKWAVETOUR,
11 PICKWAVETOURSEQ,
12 PRODRUNNR,
13 PRODRUNDATE,
14 PRODRUNFINAL,
15 PRODRUNID
16 )
17 as
18 select value(CUST),
19 EXTRACTVALUE(VALUE(CUST), '/Customer/Cust'),
20 EXTRACTVALUE(VALUE(CUST), '/Customer/Mod'),
21 EXTRACTVALUE(VALUE(CUST), '/Customer/Tod'),
22 TO_NUMBER(EXTRACTVALUE(VALUE(CUST), '/Customer/Seq')),
23 PICKWAVENR,
24 PICKWAVEPRODLINE,
25 PICKWAVETOUR,
26 PICKWAVETOURSEQ,
27 PRODRUNNR,
28 PRODRUNDATE,
29 PRODRUNFINAL,
30 PRODRUNID
31 from PICK_WAVE_VIEW, table(xmlsequence(extract(PICKWAVENODE,'/PickWave/Customer'))) CUST
32 /
View created.
Elapsed: 00:00:00.10
SQL>
SQL> create or replace view INVOICE_ORDER_VIEW
2 (
3 INVORDERNR,
4 ITEM,
5 QTY,
6 PRIORITY,
7 REORDERING,
8 HLORDER,
9 DELDATE,
10 CUST,
11 MOD,
12 TOD,
13 SEQ,
14 PICKWAVENR,
15 PICKWAVEPRODLINE,
16 PICKWAVETOUR,
17 PICKWAVETOURSEQ,
18 PRODRUNNR,
19 PRODRUNDATE,
20 PRODRUNFINAL,
21 PRODRUNID
22 )
23 as
24 SELECT EXTRACTVALUE(VALUE(INV), '/InvOrder/Nr'),
25 EXTRACTVALUE(VALUE(INV), '/InvOrder/Item'),
26 EXTRACTVALUE(VALUE(INV), '/InvOrder/Qty'),
27 EXTRACTVALUE(VALUE(INV), '/InvOrder/Priority'),
28 EXTRACTVALUE(VALUE(INV), '/InvOrder/Reordering'),
29 EXTRACTVALUE(VALUE(INV), '/InvOrder/HlOrder'),
30 TO_DATE(EXTRACTVALUE(VALUE(INV), '/InvOrder/DelDate'),'DDMMYYYY'),
31 CUST,
32 MOD,
33 TOD,
34 SEQ,
35 PICKWAVENR,
36 PICKWAVEPRODLINE,
37 PICKWAVETOUR,
38 PICKWAVETOURSEQ,
39 PRODRUNNR,
40 PRODRUNDATE,
41 PRODRUNFINAL,
42 PRODRUNID
43 FROM CUSTOMER_VIEW, table(xmlsequence(extract(CUSTOMERNODE,'Customer/InvOrder'))) INV
44 /
View created.
Elapsed: 00:00:00.13
SQL> select * from INVOICE_ORDER_VIEW
2 /
IIO0000461 100000036 20 1 0 CSO000743 15-NOV-05 100000013
FO DDU 6 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000463 100000045 20 1 0 CSO000743 15-NOV-05 100000013
FO DDU 6 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000473 100000036 20 1 0 CSO000746 15-NOV-05 100000143
FO DDU 7 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000475 100000045 20 1 0 CSO000746 15-NOV-05 100000143
FO DDU 7 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000469 100000036 20 1 0 CSO000745 15-NOV-05 100000140
FO DDU 3 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000471 100000045 20 1 0 CSO000745 15-NOV-05 100000140
FO DDU 3 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000489 100000036 20 0 0 CSO000751 15-NOV-05 100000148
FO DDU 10 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000491 100000045 20 1 0 CSO000751 15-NOV-05 100000148
FO DDU 10 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000481 100000036 20 0 0 CSO000748 15-NOV-05 100000146
FO DDU 9 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000483 100000045 20 1 0 CSO000748 15-NOV-05 100000146
FO DDU 9 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000485 100000036 20 0 0 CSO000750 15-NOV-05 100000147
FO DDU 4 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000487 100000045 20 1 0 CSO000750 15-NOV-05 100000147
FO DDU 4 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000457 100000036 20 1 0 CSO000742 15-NOV-05 100000006
FO DDU 5 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000459 100000045 20 1 0 CSO000742 15-NOV-05 100000006
FO DDU 5 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000477 100000036 20 1 0 CSO000747 15-NOV-05 100000145
FO DDU 8 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000479 100000045 20 1 0 CSO000747 15-NOV-05 100000145
FO DDU 8 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000465 100000036 20 1 0 CSO000744 15-NOV-05 100000114
FO DDU 2 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
IIO0000467 100000045 20 1 0 CSO000744 15-NOV-05 100000114
FO DDU 2 IPW0000017 1 00000043_078
1
5 15-NOV-05 1 10
18 rows selected.
Elapsed: 00:00:00.22
Execution Plan
Plan hash value: 1730223965
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 18 | 10278 | 877 (0)| 00:00:11 |
| 1 | NESTED LOOPS | | 18 | 10278 | 877 (0)| 00:00:11 |
| 2 | NESTED LOOPS | | 18 | 8424 | 841 (0)| 00:00:11 |
| 3 | MERGE JOIN CARTESIAN | | 18 | 4680 | 805 (0)| 00:00:10 |
| 4 | TABLE ACCESS FULL | XML_ORDERS | 1 | 67 | 3 (0)| 00:00:01 |
| 5 | BUFFER SORT | | 18 | 3474 | 802 (0)| 00:00:10 |
| 6 | INDEX FAST FULL SCAN| SYS_IOT_TOP_64187 | 18 | 3474 | 802 (0)| 00:00:10 |
|* 7 | INDEX UNIQUE SCAN | SYS_IOT_TOP_64185 | 1 | 208 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | SYS_C008783 | 1 | | 0 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | SYS_IOT_TOP_64183 | 1 | 103 | 2 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | SYS_C008785 | 1 | | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
7 - access("NESTED_TABLE_ID"="CUSTOMER_TAB"."SYS_NC0000800009$")
8 - access("NESTED_TABLE_ID"="CUSTOMER_TAB"."SYS_NC0000800009$")
9 - access("NESTED_TABLE_ID"="PICKWAVE_TAB"."SYS_NC0000800009$")
filter("NESTED_TABLE_ID"="XML_ORDERS"."SYS_NC0001000011$")
10 - access("NESTED_TABLE_ID"="PICKWAVE_TAB"."SYS_NC0000800009$")
Note
- dynamic sampling used for this statement
SQL> quit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
C:\oracle\xdb\otn\347125>You were sequencing the ProdRun node, which is a mistake. Only nodes which occur multiple times should be sequenced... -
Hi,
I am trying to spool data from tables into flat files. I am using the following scripts to accomplish it
1. A cmd file (windows) that makes a call to a sql file
2. The SQL file which generates another query file at the run time, depending upon the table name passed to it
3. The run time query file , that executes the final query and spools the data into a txt file | delimited
For eg:
Actual command passed C:\Spool_utility\spool_utility TABLE_NAME
Eg of the spool utility file :
@echo off
SET dbuser=XX@YY
SET dbpw=xxxx
echo %date% - %time% - Start > %1%log.txt
echo START
sqlplus -s %dbuser%/%dbpw% @spool_utility.sql %1>%1.txt
echo %date% - %time% - Done >> %1%log.txt
echo DONE
Eg of the spool_utility.sql
set echo off
SET newpage 0
SET feedback off
SET linesize 32767
set pagesize 0
SET wrap off
SET recsep off
SET con off
SET trim on
SET trims on
set verify off
SET doc off
SET termout off
SET arraysize 5000
SET HEADING off
set colsep "|"
spool &1.sql;
Prompt Select * from &1 where some condition
spool off
set termout ON
@ &1
EXIT
The above file generates a table_name.sql file with the actual table name at run time and gets executed and the output is written to the table_name.txt file.
This works perfectly fine. But the issue is when someone passes some wrong table name or if there is a actual run time error while executing the query , the error with details itself itself gets written to the end spool file.
For eg : if i do this just to generate an error and execute it from command line, the query generates an error and writes the error to the spool file , but at the command prompt where I executed the command I do not see any error and the process seems to have run perfectly well
set xxx on xxx off as above
spool &1.sql;
Prompt Select * from &1 where rownum><10---this will cause the issue
spool off
set termout ON
@ &1
EXIT
Eg of spool file generated :
from table_name WHERE rownum><=10 *
ERROR at line 62:
ORA-00936: missing expression
My question is, is there any way i can capture this runtime error and return this error to my calling sql script spool_utility.sql and then propagate it to the calling command file and do some tasks for eg removing the spool file and writing the actual error to a log file . Basically any way to know at my OS calling level that the entire spooling operation was unsuccessful.
ThanksThanks for the reply.
Querying the data dictionary will work only when the issue is a invalid table name. My question is can i capture any run time error, not only incorrect table name.
If there is any run time error (for eg the one I showed where I used a >< sign which is a invalid operator) the error gets written to my spool file, but there is no way I am able to capture that in my calling sql script and subsequently in the calling command file so that I can do something with the error. For eg if a spool file may get written with error messages, some batch process or user may pick up the spool file and start processing which i dont want to happen. i would like to trap that error or at least be notified of the error at my outer calling sql file or outer command file level, so that I can write the error to a log file and delete the erroneous spool file etc. -
What are ROWID and ROWNUM? Are they stored in database and where?
Hi All,
can anybody please answer this question
What are ROWID and ROWNUM? Are they stored in database and where?
Thanks,
SriniROWID can be thought of as a pointer to the physical location (on disk) of the (table) row.
From a ROWID value, Oracle can extract the file, block-within-that-file and offset-of-the-row-within-that-block. Using these, Oracle can directly access a disk block to retrieve a row.
ROWNUM is a just sequence number of a row within a result set of a query.
As said by other repliers, both are not stored. They are 'constructed' when you reference them inside a query. -
Is rank() really better than rownum for top-n-queries?
Several sources say that for Oracle databases rank() should be used instead of 'rownum <= n' for top-n-queries. But here we have an application, where we a lot of top-n queries are executed on a big table with several million rows and rank() has a quite bad performance. I get much better results when I use a query with rownum <= n but the programmer of the application doesn't want to change it in the software because of those articles about rank() and rownum. I wonder, whether it is possible, to find a better form of the rank()-query or an additional index, that gives me the same performance.
To explain my case I created the following example (if you try it, be aware that depending on the size of your dba_objects view you might need up to half a gig free space in your tablespace for this example).
create table big_objects
as
select
ascii(m.alpha)*100000+o.object_id object_id,
o.owner owner,
o.object_type,
m.alpha||'_'||o.object_name object_name,
sysdate-400+mod(100*object_id+99*ascii(m.alpha),365)+24/(o.object_id+ascii(m.alpha)) created,
o.status
from
(select distinct
upper(substr(object_name,1,1)) alpha
from
sys.dba_objects
where
upper(substr(object_name,1,1)) between 'A' and 'Z') m,
sys.dba_objects o
order by
object_name;
create index bigindex_1 on big_objects (owner, object_type, created);
analyze table big_objects compute statistics;
So my table looks a bit like dba_objects but with much more rows and I made a synthetic "created" date which is more similar to my real case, where top-n means a date selection of the newest records from a certain type.
Here is the size of the segments on an nearly empty 11gR2 database:
select segment_name, bytes, blocks from sys.dba_segments where segment_name like 'BIG%'
SEGMENT_NAME BYTES BLOCKS
BIGINDEX_1 75497472 9216
BIG_OBJECTS 142606336 17408
On my database the example table has approx. 1,9 Mio rows:
select count(*) from big_objects;
COUNT(*)
1884246
and some 1,4% of those rows have owner = 'SYS' and object_type = 'INDEX'
select
count(*)
from big_objects
where owner = 'SYS'
and object_type = 'INDEX';
COUNT(*)
25896
But I want to find only the 10 newest indexes for the owner SYS. I think the typical rank() approach would be:
select
owner,
object_type,
object_name,
object_id,
status,
created
from
( select
owner,
object_type,
object_name,
object_id,
status,
created,
rank() over (order by created desc) rnk
from
big_objects
where
owner = 'SYS'
and object_type = 'INDEX')
where rnk <= 10
order by created asc;
OWNER OBJECT_TYPE OBJECT_NAME OBJECT_ID STATUS CREATED
SYS INDEX B_COLLELEMIND 6600515 VALID 15.04.2010 19:05:55
SYS INDEX V_I_WRI$_OPTSTAT_IND_OBJ#_ST 8600466 VALID 15.04.2010 19:09:03
SYS INDEX G_I_RLS 7100375 VALID 15.04.2010 19:23:55
SYS INDEX V_I_DIR$SERVICE_UI 8600320 VALID 15.04.2010 19:31:33
SYS INDEX L_I_TSM_DST2$ 7600308 VALID 15.04.2010 19:36:26
SYS INDEX L_I_IDL_UB11 7600235 VALID 15.04.2010 19:57:34
SYS INDEX V_I_VIEWTRCOL1 8600174 VALID 15.04.2010 20:19:21
SYS INDEX L_I_TRIGGER2 7600162 VALID 15.04.2010 20:31:39
SYS INDEX L_I_NTAB1 7600089 VALID 15.04.2010 21:35:53
SYS INDEX B_I_SYN1 6600077 VALID 15.04.2010 22:08:07
10 rows selected.
Elapsed: 00:00:00.22
Execution Plan
Plan hash value: 2911012437
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1427 | 188K| 1400 (1)| 00:00:17 |
| 1 | SORT ORDER BY | | 1427 | 188K| 1400 (1)| 00:00:17 |
|* 2 | VIEW | | 1427 | 188K| 1399 (1)| 00:00:17 |
|* 3 | WINDOW SORT PUSHED RANK | | 1427 | 79912 | 1399 (1)| 00:00:17 |
| 4 | TABLE ACCESS BY INDEX ROWID| BIG_OBJECTS | 1427 | 79912 | 1398 (0)| 00:00:17 |
|* 5 | INDEX RANGE SCAN | BIGINDEX_1 | 1427 | | 9 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("RNK"<=10)
3 - filter(RANK() OVER ( ORDER BY INTERNAL_FUNCTION("CREATED") DESC )<=10)
5 - access("OWNER"='SYS' AND "OBJECT_TYPE"='INDEX')
Statistics
1 recursive calls
0 db block gets
25870 consistent gets
0 physical reads
0 redo size
1281 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
10 rows processed
As from the index only the first two columns are used, all the 25896 records that I found above are read and sorted just to find the ten newest ones. Many unnecessary blocks are read and luckily all needed database blocks were in memory already. In our real case quite often a lot of physical reads are performed, which makes the performance of the application even worse.
In my following example with a "rownum <= 10" all three columns of the index are used and the number of block gets is much, much smaller than in the rank() example.
select
owner,
object_type,
object_name,
object_id,
status,
created
from
big_objects
where
(owner, object_type, created)
in
( select
owner,
object_type,
created
from
( select /*+ first_rows(10) */
owner,
object_type,
created
from
big_objects
where
owner = 'SYS'
and object_type = 'INDEX'
order by
owner,
object_type,
created desc
where rownum <= 10
order by created asc;
OWNER OBJECT_TYPE OBJECT_NAME OBJECT_ID STATUS CREATED
SYS INDEX B_COLLELEMIND 6600515 VALID 15.04.2010 19:05:55
SYS INDEX V_I_WRI$_OPTSTAT_IND_OBJ#_ST 8600466 VALID 15.04.2010 19:09:03
SYS INDEX G_I_RLS 7100375 VALID 15.04.2010 19:23:55
SYS INDEX V_I_DIR$SERVICE_UI 8600320 VALID 15.04.2010 19:31:33
SYS INDEX L_I_TSM_DST2$ 7600308 VALID 15.04.2010 19:36:26
SYS INDEX L_I_IDL_UB11 7600235 VALID 15.04.2010 19:57:34
SYS INDEX V_I_VIEWTRCOL1 8600174 VALID 15.04.2010 20:19:21
SYS INDEX L_I_TRIGGER2 7600162 VALID 15.04.2010 20:31:39
SYS INDEX L_I_NTAB1 7600089 VALID 15.04.2010 21:35:53
SYS INDEX B_I_SYN1 6600077 VALID 15.04.2010 22:08:07
10 rows selected.
Elapsed: 00:00:00.03
Execution Plan
Plan hash value: 3360237620
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10 | 760 | 17 (0)| 00:00:01 |
| 1 | SORT ORDER BY | | 10 | 760 | 17 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 10 | 760 | 17 (0)| 00:00:01 |
| 4 | VIEW | VW_NSO_1 | 10 | 200 | 2 (50)| 00:00:01 |
| 5 | HASH UNIQUE | | 10 | 200 | 4 (25)| 00:00:01 |
|* 6 | COUNT STOPKEY | | | | | |
| 7 | VIEW | | 11 | 220 | 3 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN DESCENDING| BIGINDEX_1 | 1427 | 28540 | 3 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | BIGINDEX_1 | 3 | | 2 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID | BIG_OBJECTS | 3 | 168 | 6 (0)| 00:00:01 |
Predicate Information (identified by operation id):
6 - filter(ROWNUM<=10)
8 - access("OWNER"='SYS' AND "OBJECT_TYPE"='INDEX')
9 - access("OWNER"="OWNER" AND "OBJECT_TYPE"="OBJECT_TYPE" AND "CREATED"="CREATED")
Statistics
1 recursive calls
0 db block gets
26 consistent gets
0 physical reads
0 redo size
1281 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
10 rows processed
I made this comparison with the Oracle versions 10.2 and 11.2 and the result was more or less the same. How can I change the rank() query in a way that only the small number of really needed blocks are read from the database?this was exactly the hint, I was looking for. Generally speaking hints are not the preferred way to go to tune queries. They can have nasty side-effects when data changes.
Now the rank()-query is similar fast and much better to read than my fast one with three nested SELECTs.
Your rownum query was needlessly complicated, and could be simplified to:
select owner, object_type, object_name, object_id, status, created
from (select owner, object_type, created
from big_objects
where owner = 'SYS' and
object_type = 'INDEX'
order by created desc)
where rownum <= 10
order by created ascand very likely get the same speed.
One more question. How did you format those sql queries and results. When I copy/paste them into the editor of forums.oracle.com the format allways gets lost.To preserve formatting use {noformat}{noformat} before and after the section you want ot keep formatted. In general, if you want to see how someone generated an effect, reply to the post and hit the quote original icon. You will see all the formatting codes used in the original.
John -
Sender JDBC Adapter : Urgent Question
Hi,
I am working on a Oracle - XI - R/3 scenario. This scenario is working fine currently. The question that I have is what if I more than 500,000 records existing in the oracle table, then how many records will be picked up by the adapter when it polls the Oracle table . Will it try to pick up all the records, or does it pick up records in small packages..Can I set up the package size somewhere ??
I havent found an option in the adapter as such, and do not have high volumes of data in the Oracle table yet, so havent been able to run tests myself.
Thanks a lot
Any help will be appreciated
MayankBhavesh, Tim, Sandro ..
Thanks for giving me ideas in getting my issue resolved. I think I have the solution finally. I controlled the data being selected using the
SQL Query Statement " select * from zbwxi where rownum < 5000 and readflag = 'U' " and in the
update sql statement I put " update zbwxi set READFLAG = 'P' where rownum < 5000 and readflag = 'U' .
ZBWXI was by Oracle table which has a field called readflag.
I have run a few tests and the results look good to me ..
Let me know if you need explanation on why this worked ..
thanks for all your help
Mayank -
Hi,
I am trying to run this select query below and the IF-THEN-ELSE statement is not working... I am basically trying to update the CUSTOMER.CUST_OPT_IN_RENTAL_IND column with 'N' flag to 'Y' WHERE cust_classif_tr3_FULL_NM ='VIP Program'
and CUST_OPT_IN_RENTAL_IND ='N'
and CUST_EMAIL_ADDR_IND = 'Y'
AND CUST_STAT_TR2_FULL_NM='Active' to be included in the query below. can anyone help please?
SELECT
CUSTOMER.CUSTOMER_SSKEY CUSTOMER_sskey,
TO_CHAR(( CUSTOMER.DATE_MODIFIED ),'MM/DD/YYYY') date_modified,
NVL(( CUSTOMER.SRC_CUST_ID ),( 'UNKNOWN' )) SRC_CUST_ID,
NVL(( CUSTOMER.EXTNL_CUST_ID ),( 'UNKNOWN' )) EXTNL_CUST_ID,
NVL(( TO_CHAR(( CUSTOMER.LAST_UPDATE_DT ),'MM/DD/YYYY') ),( '01/01/1900' )) LAST_UPDATE_DT,
NVL(( CUSTOMER.SUB_CONTNT_CD ),( 'UNKNO' )) SUB_CONTNT_CD,
NVL(( CUSTOMER.SUB_CONTNT_NM ),( 'UNKNOWN' )) SUB_CONTNT_NM,
DECODE((CUST_EMAIL_ADDR_IND ),( 'N' ),( '-')
, ( 'Y' ), ( 'EPITEST'|| LPAD(MOD(ROWNUM,100),3,'0')||'@INTERVALINTL.COM')
) email_address,
IF CUSTOMER.CUST_OPT_IN_RENTAL_IND :='N' THEN result :='Y';
ELSIF CUSTOMER.CUST_OPT_IN_RENTAL_IND :='N' THEN result := 'VIP Program' cust_classif_tr3_FULL_NM;
ELSIF CUSTOMER.CUST_OPT_IN_RENTAL_IND :='N' THEN result := 'Y' CUST_EMAIL_ADDR_IND;
ELSIF CUSTOMER.CUST_OPT_IN_RENTAL_IND :='N' THEN result := 'Active' CUST_STAT_TR2_FULL_NM;
ELSIF
END IF;
NVL(( CUSTOMER.EMAIL_FORMAT_PREF ),( 'UNKNOWN' )) email_format_pref,
NVL(( TRUNC( CUSTOMER.EMAIL_UNDELIVERABLE_COUNT ) ),( -1 )) email_undeliverable_count,
NVL(( CUSTOMER.EMAIL_HTML_CAPABILITY ),( 'UNKNOWN' )) email_html_capability,
NVL(( CUSTOMER.EMAIL_UNSUBSCRIBE ),( 'UNKNOWN' )) email_unsubscribe,
NVL(( CUSTOMER.CUST_ID ),( 0 )) CUST_ID,
NVL(( CUSTOMER.ONLINE_PROFILE_FIRST_NAME ),( 'UNKNOWN' )) ONLINE_PROFILE_FIRST_NAME,
NVL(( CUSTOMER.ONLINE_PROFILE_LAST_NAME ),( 'UNKNOWN' )) ONLINE_PROFILE_LAST_NAME,
NVL(( CUSTOMER.GOLD_BILL_TYPE_TR1_CD ),( 'UNKNO' )) GOLD_BILL_TYPE_TR1_CD,
NVL(( CUSTOMER.GOLD_BILL_TYPE_TR1_FULL_NM ),( 'UNKNOWN' )) GOLD_BILL_TYPE_TR1_FULL_NM,
NVL(( CUSTOMER.GOLD_BILL_TYPE_TR2_CD ),( 'UNKNO' )) GOLD_BILL_TYPE_TR2_CD
FROM
CUSTOMERSTAGE CUSTOMER
Thanks,
SophHi, Soph,
Welcome to the forum!
Whenever you hav a question, post a little sample data (CREATE TABLE and INSERT statments) and the resutls you want from that data.
In the case of a DML problem (such as UPDATE), the sample data should show what the tabels are like before the change, and the reuslts will be the contents of the changed table after it.
Always say what version of Oracle you're using.
Without that, people will still try to help you as much as they can, but that won't be much.
IF-THEN-ELSE is PL/SQL. You can't use PL/SQL statements in the middle of a SQL staement, such as SELECT, even if the SQL statement is being doen within PL/SQL.
Instead of IF-THEN-ELSE, you can use CASE in SQL, or, in some special situations, DECODE.
Here's an example of using CASE:
Say you have a column in your table called cust_opt_in_rental, and it could have the values 'N'. 'N1', 'N2' or 'N3'.
You want to produce a column in your result set called result, which will be derived from cust_opt_in_rental.
If cust_opt_in_rental is 'N', then result should be ''Y'
If cust_opt_in_rental is 'N1', then result should be 'VIP Program' followed by the column cust_classif_tr3_FULL_NM
If cust_opt_in_rental is 'N2', then result should be 'Y' followed by the column CUST_EMAIL_ADDR_IND
If cust_opt_in_rental is 'N3', then result should be 'Active' fololowed by the column CUST_STAT_TR2_FULL_NM
You can do that using CASE like this:
SELECT CASE customer.cust_opt_in_rental_ind
WHEN 'N' THEN 'Y';
WHEN 'N1' THEN 'VIP Program ' || cust_classif_tr3_full_nm
WHEN 'N2' THEN 'Y ' || cust_email_addr_ind
WHEN 'N3' THEN 'Active ' || cust_stat_tr2_full_nm
END AS result
FROM ...This is one situation where DECODE would work as well. -
I'm having a couple of issues with a query, and I can't figure out the best way to reach a solution.
Platform Information
Windows Server 2003 R2
Oracle 10.2.0.4
Optimizer Settings
SQL > show parameter optimizer
NAME TYPE VALUE
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 10.2.0.4
optimizer_index_caching integer 90
optimizer_index_cost_adj integer 30
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUEThe query below, is a simple "Top N" query, where the top result is returned. Here it is, with bind variables in the same location as the application code:
SELECT PRODUCT_DESC
FROM
SELECT PRODUCT_DESC
, COUNT(*) AS CNT
FROM USER_VISITS
JOIN PRODUCT ON PRODUCT.PRODUCT_OID = USER_VISITS.PRODUCT_OID
WHERE PRODUCT.PRODUCT_DESC != 'Home'
AND VISIT_DATE
BETWEEN
ADD_MONTHS
TRUNC
TO_DATE
:vCurrentYear
, 'YYYY'
, 'YEAR'
, 3*(:vCurrentQuarter-1)
AND
ADD_MONTHS
TRUNC
TO_DATE
:vCurrentYear
, 'YYYY'
, 'YEAR'
, 3*:vCurrentQuarter
) - INTERVAL '1' DAY
GROUP BY PRODUCT_DESC
ORDER BY CNT DESC
WHERE ROWNUM <= 1;
Explain Plan
The explain plan I receive when running the query above.
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
|* 1 | COUNT STOPKEY | | 1 | | 1 |00:00:34.92 | 66343 | | | |
| 2 | VIEW | | 1 | 1 | 1 |00:00:34.92 | 66343 | | | |
|* 3 | FILTER | | 1 | | 1 |00:00:34.92 | 66343 | | | |
| 4 | SORT ORDER BY | | 1 | 1 | 1 |00:00:34.92 | 66343 | 2048 | 2048 | 2048 (0)|
| 5 | SORT GROUP BY NOSORT | | 1 | 1 | 27 |00:00:34.92 | 66343 | | | |
| 6 | NESTED LOOPS | | 1 | 2 | 12711 |00:00:34.90 | 66343 | | | |
| 7 | TABLE ACCESS BY INDEX ROWID| PRODUCT | 1 | 74 | 77 |00:00:00.01 | 44 | | | |
|* 8 | INDEX FULL SCAN | PRODUCT_PRODDESCHAND_UNQ | 1 | 1 | 77 |00:00:00.01 | 1 | | | |
|* 9 | INDEX FULL SCAN | USER_VISITS#PK | 77 | 2 | 12711 |00:00:34.88 | 66299 | | | |
Predicate Information (identified by operation id):
1 - filter(ROWNUM<=1)
3 - filter(ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURRENTYEAR),'YYYY'),'fmyear'),3*(:VCURRENTQUARTER-1))<=ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURR
ENTYEAR),'YYYY'),'fmyear'),3*:VCURRENTQUARTER)-INTERVAL'+01 00:00:00' DAY(2) TO SECOND(0))
8 - filter("PRODUCT"."PRODUCT_DESC"<>'Home')
9 - access("USER_VISITS"."VISIT_DATE">=ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURRENTYEAR),'YYYY'),'fmyear'),3*(:VCURRENTQUARTER-1)) AND
"USER_VISITS"."PRODUCT_OID"="PRODUCT"."PRODUCT_OID" AND "USER_VISITS"."VISIT_DATE"<=ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURRENTYEAR),'YYYY')
,'fmyear'),3*:VCURRENTQUARTER)-INTERVAL'+01 00:00:00' DAY(2) TO SECOND(0))
filter(("USER_VISITS"."VISIT_DATE">=ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURRENTYEAR),'YYYY'),'fmyear'),3*(:VCURRENTQUARTER-1)) AND
"USER_VISITS"."VISIT_DATE"<=ADD_MONTHS(TRUNC(TO_DATE(TO_CHAR(:VCURRENTYEAR),'YYYY'),'fmyear'),3*:VCURRENTQUARTER)-INTERVAL'+01 00:00:00' DAY(2)
TO SECOND(0) AND "USER_VISITS"."PRODUCT_OID"="PRODUCT"."PRODUCT_OID"))
Row Source Generation
TKPROF Row Source Generation
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.01 0 0 0 0
Fetch 2 35.10 35.13 0 66343 0 1
total 4 35.10 35.14 0 66343 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 62
Rows Row Source Operation
1 COUNT STOPKEY (cr=66343 pr=0 pw=0 time=35132008 us)
1 VIEW (cr=66343 pr=0 pw=0 time=35131996 us)
1 FILTER (cr=66343 pr=0 pw=0 time=35131991 us)
1 SORT ORDER BY (cr=66343 pr=0 pw=0 time=35131936 us)
27 SORT GROUP BY NOSORT (cr=66343 pr=0 pw=0 time=14476309 us)
12711 NESTED LOOPS (cr=66343 pr=0 pw=0 time=22921810 us)
77 TABLE ACCESS BY INDEX ROWID PRODUCT (cr=44 pr=0 pw=0 time=3674 us)
77 INDEX FULL SCAN PRODUCT_PRODDESCHAND_UNQ (cr=1 pr=0 pw=0 time=827 us)(object id 52355)
12711 INDEX FULL SCAN USER_VISITS#PK (cr=66299 pr=0 pw=0 time=44083746 us)(object id 52949)However when I run the query with an ALL_ROWS hint I receive this explain plan (reasoning for this can be found here Jonathan's Lewis' response: http://www.freelists.org/post/oracle-l/ORDER-BY-and-first-rows-10-madness,4):
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 39 | 223 (25)| 00:00:03 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 1 | 39 | 223 (25)| 00:00:03 |
|* 3 | FILTER | | | | | |
| 4 | SORT ORDER BY | | 1 | 49 | 223 (25)| 00:00:03 |
| 5 | HASH GROUP BY | | 1 | 49 | 223 (25)| 00:00:03 |
|* 6 | HASH JOIN | | 490 | 24010 | 222 (24)| 00:00:03 |
|* 7 | TABLE ACCESS FULL | PRODUCT | 77 | 2849 | 2 (0)| 00:00:01 |
|* 8 | INDEX FAST FULL SCAN| USER_VISITS#PK | 490 | 5880 | 219 (24)| 00:00:03 |
Predicate Information (identified by operation id):
1 - filter(ROWNUM<=1)
3 - filter(ADD_MONTHS(TRUNC(TO_DATE(:VCURRENTYEAR,'YYYY'),'fmyear'),3*(TO_NUMBER(:
VCURRENTQUARTER)-1))<=ADD_MONTHS(TRUNC(TO_DATE(:VCURRENTYEAR,'YYYY'),'fmyear'),3*TO_N
UMBER(:VCURRENTQUARTER))-INTERVAL'+01 00:00:00' DAY(2) TO SECOND(0))
6 - access("USER_VISITS"."PRODUCT_OID"="PRODUCT"."PRODUCT_OID")
7 - filter("PRODUCT"."PRODUCT_DESC"<>'Home')
8 - filter("USER_VISITS"."VISIT_DATE">=ADD_MONTHS(TRUNC(TO_DATE(:VCURRENTYEAR,'YYY
Y'),'fmyear'),3*(TO_NUMBER(:VCURRENTQUARTER)-1)) AND
"USER_VISITS"."VISIT_DATE"<=ADD_MONTHS(TRUNC(TO_DATE(:VCURRENTYEAR,'YYYY'),'fmyear'),
3*TO_NUMBER(:VCURRENTQUARTER))-INTERVAL'+01 00:00:00' DAY(2) TO SECOND(0))And the TKPROF Row Source Generation:
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 3 0.51 0.51 0 907 0 27
total 5 0.51 0.51 0 907 0 27
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 62
Rows Row Source Operation
27 FILTER (cr=907 pr=0 pw=0 time=513472 us)
27 SORT ORDER BY (cr=907 pr=0 pw=0 time=513414 us)
27 HASH GROUP BY (cr=907 pr=0 pw=0 time=512919 us)
12711 HASH JOIN (cr=907 pr=0 pw=0 time=641130 us)
77 TABLE ACCESS FULL PRODUCT (cr=5 pr=0 pw=0 time=249 us)
22844 INDEX FAST FULL SCAN USER_VISITS#PK (cr=902 pr=0 pw=0 time=300356 us)(object id 52949)The query with the ALL_ROWS hint returns data instantly, while the other one takes about 70 times as long.
Interestingly enough BOTH queries generate plans with estimates that are WAY off. The first plan is estimating 2 rows, while the second plan is estimating 490 rows. However the real number of rows is correctly reported in the Row Source Generation as 12711 (after the join operation).
TABLE_NAME NUM_ROWS BLOCKS
USER_VISITS 196044 1049
INDEX_NAME BLEVEL LEAF_BLOCKS DISTINCT_KEYS CLUSTERING_FACTOR LAST_ANALYZED
USER_VISITS#PK 2 860 196002 57761 07/24/2009 13:17:59
COLUMN_NAME NUM_DISTINCT LOW_VALUE HIGH_VALUE DENSITY NUM_NULLS HISTOGRAM
VISIT_DATE 195900 786809010E0910 786D0609111328 .0000051046452272 0 NONEI don't know how the first one is estimating 2 rows, but I can compute the second's cardinality estimates by assuming a 5% selectivity for the TO_DATE() functions:
SQL > SELECT ROUND(0.05*0.05*196044) FROM DUAL;
ROUND(0.05*0.05*196044)
490However, removing the bind variables (and clearing the shared pool), does not change the cardinality estimates at all.
I would like to avoid hinting this plan if possible and that is why I'm looking for advice. I also have a followup question.
Edited by: Centinul on Sep 20, 2009 4:10 PM
See my last post for 11.2.0.1 update.Centinul wrote:
You could potentially perform testing with either a CARDINALITY or OPT_ESTIMATE hint to see if the execution plan changes dramatically to improve performance. The question then becomes > whether this be sufficient to over-rule the first rows optimizer so that it does not use an index access which will avoid a sort.I tried doing that this morning by increasing the cardinality from the USER_VISITS table to a value such that the estimate was about that of the real amount of data. However the plan did not change.
Could you use the ROW_NUMBER analytic function instead of ROWNUMInterestingly enough, when I tried this it generated the same plan as was used with the ALL_ROWS hint, so I may implement this query for now.
I do have two more followup questions:
1. Even though a better plan is picked the optimizer estimates are still off by a large margin because of bind variables and 5%* 5% * NUM_ROWS. How do I get the estimates in-line with the actual values? Should I really fudge statistics?
2. Should I raise a bug report with Oracle over the behavior of the original query?That is great that the ROW_NUMBER analyitic function worked. You may want to perform some testing with this before implementing it in production to see whether Oracle performs significantly more logical or physical I/Os with the ROW_NUMBER analytic function compared to the ROWNUM solution with the ALL_ROWS hint.
As Timur suggests, seeing a 10053 trace during a hard parse of both queries (with and without the ALL_ROWS hint) would help determine what is happening. It could be that a histogram exists which is feeding bad information to the optimizer, causing distorted cardinality in the plan. If bind peeking is used, the 5% * 5% rule might not apply, especially if a histogram is involved. Also, the WHERE clause includes "PRODUCT.PRODUCT_DESC != 'Home'" which might affect the cardinality in the plan.
Your question may have prompted the starting of a thread in the SQL forum yesterday on the topic of ROWNUM, but it appears that thread was removed from the forum within the last couple hours.
Charles Hooper
IT Manager/Oracle DBA
K&M Machine-Fabricating, Inc.
Maybe you are looking for
-
Error Activating Message Mapping
HI All, I am getting the below error when i try to activate any message mapping in the IR. Any ideas? " Starting compilation Source code has syntax error: java.lang.NoClassDefFoundError: com/sun/tools/javac/Main Exception in thread "main" Thank you
-
In what world is this update beautiful? ugly. some good additions are great, but the interface is far from beautiful, hard to read, annoying and with a very childlike look. Can you give us options to put it back to look like it did prior to 7 updat
-
IR - easy way to change the items
Hello, When you recive an invoice for a purchase order and the quantity of the GR is not the same as what was on the PO but the invoice does there is a quantity differece, the users have to manually change the items on the invoice from the quantity r
-
Can I open a SSLServerSocket on a mobile phone supporting MIDP2.0
If you know if I can open a SSLServerSocket on a mobile phone, please send email to [email protected] Thanks.
-
Hi, My Scenario is to create document in CV01N, For documents from type 'PAL' in status u201Cready to approveu201D it is not allowed to create a new document version due to the fact that the status u201Cready to approveu201D triggers a new DMS workf