Order by clause in PL/SQL cursors
I am trying to execute a procedure with some input parameters. I open a cursor
with a select statement. However, the order by clause in the query does not
recognize parameter sent through the procedure input parameters.
For example:
open <<cursor name>> for
select id from member order by <<dynamic parameter>>" does not work (Compiles fine but does not return the right result).
But if I try and give a static order by <<column name>> it works. Is the
order by clause in the PL/SQL a compile time phenomenon?
I have also tried it through dynamic sql. All the other parameters work except the order by <<parameter>> asc|desc
Also "asc" and "desc" does not work if given dynamically.
What alternatives do I have?
null
I don't think order by can be dynamic in a cursor, but it sure can be using dynamic sql. The only issue is that you must do a replace in the sql string with the dynamic variable. For example:
create or replace procedure test_dyn(p_col in varchar2, p_order in varchar2) as
q varchar2(500);
u_exec_cur number;
u_columnnumber NUMBER;
u_columndate DATE;
u_columnvarchar varchar2(50);
u_cur_count number;
u_ename varchar2(20);
u_sal number;
begin
q := 'select ename, sal from scott.emp order by p_col p_order';
-- got to do these two replaces
q:= replace(q,'p_col',p_col);
q:= replace(q,'p_order',p_order);
u_exec_cur := dbms_sql.open_cursor;
dbms_sql.parse(u_exec_cur,q,dbms_sql.v7);
dbms_sql.define_column(u_exec_cur, 1, u_columnvarchar, 20);
dbms_sql.define_column(u_exec_cur, 2, u_columnnumber);
u_cur_count := dbms_sql.execute(u_exec_cur);
loop
exit when (dbms_sql.fetch_rows(u_exec_cur) <= 0);
dbms_sql.column_value(u_exec_cur, 1, u_ename);
dbms_sql.column_value(u_exec_cur, 2, u_sal);
dbms_output.put_line(u_ename);
dbms_output.put_line(u_sail);
--htp.p(u_ename);
--htp.p(u_sal);
end loop;
end;
show errors;
Now when when I execute my procedure I can change the order by clause all I want, for example:
SQL> set serveroutput on;
SQL> exec gmika.test_dyn('sal','asc');
SMITH
800
ADAMS
1100
WARD
1250
MARTIN
1250
MILLER
1300
TURNER
1500
ALLEN
1600
JLO
2222
BLAKE
2850
JONES
2975
SCOTT
3000
FORD
3000
LOKITZ
4500
KING
5000
JAMES
5151
JAMES
5555
PL/SQL procedure successfully completed.
SQL>
null
Similar Messages
-
How to make an ORDER BY clause dynamic
is there anyway to make the ORDER BY clause in an SQL query within a DB control
dynamic? I have tried to pass a String of the column name and place it in the
statement within {}, but it doesn't work"Mark" <[email protected]> wrote:
>
is there anyway to make the ORDER BY clause in an SQL query within a
DB control
dynamic? I have tried to pass a String of the column name and place
it in the
statement within {}, but it doesn't workDid you find how ? please let me know, I also need to have a dynamic order by
clause. -
Passing parameters in order by clause of cursor
Hi friends,
I am facing a strange problem
I have a cursor with a order by clause.
OPEN cursor_nomrpt FOR
SELECT DISTINCT
CAST(plano.desc3 AS VARCHAR2(50)) category
,plano.name plan_name
,nvl(CAST(plano.desc6 AS VARCHAR2(50)),'not applicable') pcrr
,nvl(trunc(plano.value18,2),0) nominal_slm
,nvl(trunc(plano.value19,2),0) blm
,plano.dbdateeffectivefrom date_live
plano.dbkey pog_id
,case when plano.value47 < 0 THEN 0 when plano.value47 IS NULL THEN 0 ELSE plano.value47 END AS parent_id
FROM
dplapro1.ix_spc_planogram plano
INNER JOIN dplapro1.ix_spc_performance perf ON plano.dbkey = perf.dbparentplanogramkey
INNER JOIN dplapro1.ix_spc_product product ON perf.dbparentproductkey = product.dbkey
INNER JOIN dplapro1.ix_spc_product_key prodkey ON product.dbkey2 = prodkey.dbkey
AND prodkey.keylevel = 2
WHERE
plano.value50 = 0
AND plano.dbkey4 = p_subcatkey
ORDER BY ltrim(rtrim(p_orderby)) ASC;
p_orderby is the parameter being passed. But the output is not sorted. But when I run the cursor by hardcoding the parameter value it works fine...
Need your help on thisHi,
When you use a local variable in a cursor, it's as if you had hard-coded a literal in its place, so you can't use a variable for a column name.
If you know all the possible values of p_orderby, you can do something like this:
ORDER BY TRIM ( CASE p_orderby
WHEN 'DESC' THEN plano.desc
WHEN 'VALUE' THEN plano.value
END
) ASC;If you don't know all the possible values, you could use dynamic SQL.
By the way,
TRIM (x)returns the same results as
LTRIM ( RTRIM (x)) -
TestStand Open SQL Statement does not support SQL's ORDER BY clause???
TestStand 1.0.3
Windows 2000 SP1
SQL Server 2000 Personal
You've got to be kidding me...
It appears that the built-in TestStand Open SQL Step does NOT support the
"ORDER BY" clause in the SELECT statement, even though the documentation
says it does. Is this true?
I have an Open SQL Statement query:
"SELECT * FROM [MyTable] WHERE ([Batch ID]=1234)"
it works fine, returning a correct record count 120 records. If I change
the Open SQL Statement query simply by adding an ORDER BY clause, such as:
"SELECT * FROM [MyTable] WHERE ([Batch ID]=1234) ORDER BY [MyField] ASC"
it returns a record count of zero. I know that "MyField" exists in the
MyTable table and contains valid data. The
second query works fine in SQL
Server Enterprise Manager.
Am I missing something? Is it true that the TestStand Open SQL Step does
NOT support the "ORDER BY" clause? If not, what &#$!ing good is it and why
does the manual state it is supported? Is there any other way using just
the TestStand steps to order a database recordset on one or more fields?
Any help would be appreciated.
Grrrrr....
Bob Rafuse
Etec Inc.> Bob -
> The database step types do not do anything special to the SQL command
> that you give it. The step just passes the command to the ADO
> provider. I tried a simple query using the step types with the
> following command,
>
> "SELECT UUT_RESULT.* FROM UUT_RESULT WHERE ([UUT_SERIAL_NUMBER] =
> 12345) ORDER BY [EXECUTION_TIME] ASC"
>
> and this return the expected results and the record count parameter
> was as expected. I tried this on TS 1.0.2 and TS 2.0 with MS Access
> 2000 and MS SQL Server 7.0. I do not have MS SQL Server 2000 at this
> time.
>
> It would be surprised if the step types are messing something up.
I've been doing some experimenting over the past couple of days. Simple,
one-table queries seem to handle the ORDER BY clause fine. Th
ings seem to
get messed up when I try multi-table queries with ORDER BY clause with the
TestStand database steps. I get no errors but the returned record counts
are always 0 with the ORDER BY and positive without the ORDER BY. The exact
same queries work fine in Visual Basic/ADO and the SQL Server Query
Analyzer.
> Questions:
> 1. Have you verified whether the data is actually returned even though
> the record count is zero?
Hmmm... yes data IS getting returned (at least on the two instances I just
checked), but the record count is always zero. I was not proceeding with
processing if the record count was 0.
Still... I don't know how to loop through the recordset without knowing how
many records there are an not eventually generate an error by passing EOF.
Is there another way using the TestStand database steps to determine a) the
number of records in the recordset or b) when I'm at EOF?
> 2. Are you using any advanced options on the Opend SQL Statement step
> type, specifically
the cursor type set to forward only? Forward only
> cursors do not allow for record counts.
Everything on the Advanced tab of the Open SQL Statement step is set to "Use
Default".
Bob. -
Problems while using ORDER BY in declaring a PL/SQL cursor
Hi, everybody
I hope you can help me.
We are programming a very simple PL/SQL Procedure where we are declaring the following Cursor:Declare
Cursor CUnidadP is
Select UNOR_CO_UNID_ORGID,UNOR_CO_PADREID,UNOR_NU_NIVEL from Unidad_Organizativa
where Unor_NU_NIVEL > 1)
order by Unor_NU_NIVEL;
(We need to have sorted records in the cursor)
Curiously, this cursor declaration works fine in our local 8.1.6 Database (in an NT machine) but it is not working in our customer Database (8.0.4.3.0 for SUN/SOLARIS)
where we are getting the following error messages:
"ORA-06550:line 3, column 9
PLS-00707:unsupported construct or internal error (2603)
ORA-06550:line 3, column 9
PL/SQL:SQL Statement ignored"
So, my question is: Anyone knows why? Is there any bug concerning to 8.0.4.3.0 version for SUN Solaris referring to this subject? Does anyone know a different way of doing this getting same results?
Thanks everybody and best regards
IreneThere is a bug with the following description:
Bug:619477
Description: Although SQL supports the ORDER BY clause in subqueries,
PL/SQL does not yet support these.
Workaround: Execute SQL statements with such subqueries through dynamic SQL.
An easier workaround is an explicit (out-of-line) view
Maybe this (or a related bug) is your problem -
Cursor ORDER BY Clause Changing Row Count In BULK COLLECT ... FOR LOOP?
Oracle 10g Enterprise Edition Release 10.2.0.4.0 running on Windows Server 2003
Oracle Client 10.2.0.2.0 running on Windows 2000
I have some PL/SQL code that's intended to update a column in a table based on a lookup from another table. I started out by testing it with the UPDATE statement commented out, just visually inspecting the DBMS_OUTPUT results to see if it was sane. During this testing I added/changed the cursor ORDER BY clause to make it easier to read the output, and saw some strange results. I've run the code 3 times with:
1. no ORDER BY clause
2. ORDER BY with two columns (neither indexed)
3. ORDER BY with one column (not indexed)
and get three different "rows updated" counts - in fact, when using the ORDER BY clauses it appears that the code is processing more rows than without either ORDER BY clause. I'm wondering why adding / changing an ORDER BY <non-indexed column> clause in a cursor would affect the row count?
The code structure is:
TYPE my_Table_t IS TABLE OF table1%ROWTYPE ;
my_Table my_Table_t ;
CURSOR my_Cursor IS SELECT * FROM table1 ; -- initial case - no ORDER BY clause
-- ORDER BY table1.column1, table1.column2 ; -- neither column indexed
-- ORDER BY table1.column2 ; -- column not indexed
my_Loop_Count NUMBER := 0 ;
OPEN my_Cursor ;
LOOP
FETCH my_Cursor BULK COLLECT INTO my_Table LIMIT 100 ;
EXIT WHEN my_Table.COUNT = 0 ;
FOR i IN 1..my_Table.COUNT LOOP
my_New_Value := <call a pkg.funct to retrieve expected value from another table> ;
EXIT WHEN my_New_Value IS NULL ;
EXIT WHEN my_New_Value = <an undesirable value> ;
IF my_New_Value <> my_Table(i).column3 THEN
DBMS_OUTPUT.PUT_LINE( 'Changing ' || my_Table(i).column3 || ' to ' || my_New_Value ) ;
UPDATE table1 SET column3 = my_New_Value WHERE column_pk = my_Table(i).column_pk ;
my_Loop_Count := my_Loop_Count + 1 ;
END IF ;
END LOOP ;
COMMIT ;
END LOOP ;
CLOSE my_Cursor ;
DBMS_OUTPUT.PUT_LINE( 'Processed ' || my_Loop_Count || ' Rows ' ) ;Hello (and welcome),
Your handling the inner cursor exit control is suspect, which will result in (seemingly) erratic record counts.
Instead of:
LOOP
FETCH my_Cursor BULK COLLECT INTO my_Table LIMIT 100 ;
EXIT WHEN my_Table.COUNT = 0 ;
FOR i IN 1..my_Table.COUNT LOOP
my_New_Value := <call a pkg.funct to retrieve expected value from another table> ;
EXIT WHEN my_New_Value IS NULL ;
EXIT WHEN my_New_Value = <an undesirable value> ;
IF my_New_Value my_Table(i).column3 THEN
DBMS_OUTPUT.PUT_LINE( 'Changing ' || my_Table(i).column3 || ' to ' || my_New_Value ) ;
UPDATE table1 SET column3 = my_New_Value WHERE column_pk = my_Table(i).column_pk ;
my_Loop_Count := my_Loop_Count + 1 ;
END IF ;
END LOOP ;
COMMIT ;
END LOOP ;Try this:
LOOP
FETCH my_Cursor BULK COLLECT INTO my_Table LIMIT 100 ;
FOR i IN 1..my_Table.COUNT LOOP
my_New_Value := <call a pkg.funct to retrieve expected value from another table> ;
EXIT WHEN my_New_Value IS NULL ;
EXIT WHEN my_New_Value = <an undesirable value> ;
IF my_New_Value my_Table(i).column3 THEN
DBMS_OUTPUT.PUT_LINE( 'Changing ' || my_Table(i).column3 || ' to ' || my_New_Value ) ;
UPDATE table1 SET column3 = my_New_Value WHERE column_pk = my_Table(i).column_pk ;
my_Loop_Count := my_Loop_Count + 1 ;
END IF ;
EXIT WHEN my_Cursor%NOTFOUND;
END LOOP ;
END LOOP ;
COMMIT ;Which also takes the COMMIT outside of the LOOP -- try to never have a COMMIT inside of any LOOP.
Additionally, not too sure about these:
my_New_Value := <call a pkg.funct to retrieve expected value from another table> ;
EXIT WHEN my_New_Value IS NULL ;
EXIT WHEN my_New_Value = <an undesirable value> ;Any one of those EXITs will bypass your my_Loop_Count increment.
Edited by: SeánMacGC on Jul 9, 2009 8:37 AM
Had the cursor not found in the wrong place, now corrected. -
Order by clause in cursor problem
Hello,
I'm unable to compile package body when i'm using order by clause in cursor subquery in stored procedure.
Sample code:
CREATE PACKAGE Announces AS
TYPE tRefCur IS REF CURSOR;
PROCEDURE TopAnnounces(
iiCount IN NUMBER,
osAnnounces OUT tRefCur,
oiRetVal OUT NUMBER
END Announces;
CREATE PACKAGE BODY Announces AS
PROCEDURE TopAnnounces(
iiCount IN NUMBER,
osAnnounces OUT NUMBER,
oiRetVal OUT NUMBER
AS
BEGIN
OPEN osAnnounces FOR
SELECT Id, Name, AnnCount FROM
SELECT Id, Name, COUNT(CategoryId) AS AnnCount FROM tblAnnounces
GROUP BY Id, Name
-- bellow is the line, where the code crash
ORDER BY AnnCount DESC
WHERE ROWNUM < iiCount + 1;
oiRetVal := 0;
EXCEPTION
WHEN OTHERS THEN
oiRetVal := -255;
END TopAnnounces;
END Announces;
If I compile the code above I will get this error:
PLS-00103: Encoutered the symbol "ORDER" when expecting on of the following:
After I remark the problematic line, the compilation is successful (but not the result :).
Is there something I'm doing wrong?
Thanks for advice
Vojtech Novacek
nullSorry you can not use order by clause into one temporal table created by subquery.
Put the order by clause offside of subquery.
Atte.
CC.
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Vojtech Novacek:
Hello,
I'm unable to compile package body when i'm using order by clause in cursor subquery in stored procedure.
Sample code:
CREATE PACKAGE Announces AS
TYPE tRefCur IS REF CURSOR;
PROCEDURE TopAnnounces(
iiCount IN NUMBER,
osAnnounces OUT tRefCur,
oiRetVal OUT NUMBER
END Announces;
CREATE PACKAGE BODY Announces AS
PROCEDURE TopAnnounces(
iiCount IN NUMBER,
osAnnounces OUT NUMBER,
oiRetVal OUT NUMBER
AS
BEGIN
OPEN osAnnounces FOR
SELECT Id, Name, AnnCount FROM
SELECT Id, Name, COUNT(CategoryId) AS AnnCount FROM tblAnnounces
GROUP BY Id, Name
-- bellow is the line, where the code crash
ORDER BY AnnCount DESC
WHERE ROWNUM < iiCount + 1;
oiRetVal := 0;
EXCEPTION
WHEN OTHERS THEN
oiRetVal := -255;
END TopAnnounces;
END Announces;
If I compile the code above I will get this error:
PLS-00103: Encoutered the symbol "ORDER" when expecting on of the following:
After I remark the problematic line, the compilation is successful (but not the result :).
Is there something I'm doing wrong?
Thanks for advice
Vojtech Novacek<HR></BLOCKQUOTE>
null -
Slow SQL output when table alias is NOT used in order by clause
Hi guys,
My query is based on Oracle 9208
I have a table TAB1 with 68000 records with transaction_id as the primary key in this table (unique index).
I have another TAB2 with the same number of records again with transaction_id in this table (foreign key to above).
I have the below query that gets executed via an application:-
SELECT TO_CHAR(V1.TRANSACTION_ID), V1.POLICY_ID, V1.REQUEST_TYPE
FROM <VIEW> V1 WHERE V1.CERT_SERIAL_NUM=56192 AND
(V1.AUTH_GROUP_ID=0 OR V1.AUTH_GROUP_ID=1) AND ROWNUM <= 3 ORDER
BY TRANSACTION_ID ASC
The above view V1 is created as below:-
CREATE OR REPLACE FORCE VIEW "V1"
("TRANSACTION_ID",
"PARENT_TRANSACTION_ID",
"CA_DN_ID",
"AUTH_GROUP_ID",
"POLICY_ID",
"REQUEST_TYPE",
"REQUEST_STATUS",
"EE_DN_HASH",
"EE_DN",
"EE_EMAIL_HASH",
"EE_EMAIL",
"KEY_USAGE",
"SMART_CARD_SERIAL",
"CERT_TYPE",
"CERT_SERIAL_NUM",
"CERT_INDEX",
"RENEWAL_FLAG",
"ARCHIVE_FLAG",
"TIME_RECEIVED",
"DOWNLOADED",
"REQUEST_DATA",
"ACTION",
"STEP_NUM")
AS
SELECT
T1.transaction_id,
T1.parent_transaction_id,
T1.ca_dn_id,
V2.auth_group_id,
V2.policy_id,
T1.request_type,
T1.request_status,
T2.ee_dn_hash,
T2.ee_dn,
T2.ee_email_hash,
T2.ee_email,
T2.key_usage,
T2.smart_card_serial,
T2.cert_type,
T2.cert_serial_num,
T2.cert_index,
T2.renewal_flag,
T2.archive_flag,
T1.time_received,
T1.downloaded,
T1.request_data,
V2.action,
V2.step_num
FROM TAB1
<ANOTHER VIEW> V2,
TAB2 T1,
TAB2 T2
WHERE
T1.transaction_id = T2.transaction_id
AND
V2.policy_id = T1.policy_id
order by transaction_id;
The query at the top runs within milliseconds if the VIEW is created as :-
order by t2.transaction_id
But without the alias "t2" in the order by, the query takes about 1 1/2 minutes
Can you tell me why? I thought if you ordering by primary key (lesser number of values compared to foreign key values), the query should be faster..no?
Thanks in advanceThanks for keeping up with this issue Hemant.
Here are the plans for each case.
I would be very interested in how you'd recognize which plan is the best and what are the derivatives.
I don't much (or rather anything!) what is 'card' values, 'cost' values etc which I believe are used to decide the best plan of the lot.
Thanks again
Note TAB1 and TAB2 are from view definition posted initially
1) Execution Plan for VIEW1 <<-- With ORDER BY" clause but no table ailas (order by transaction_id)
SQL> EXPLAIN PLAN FOR SELECT TO_CHAR(QT.TRANSACTION_ID), QT.POLICY_ID, QT.REQUEST_TYPE
2 FROM <VIEW1> QT WHERE QT.CERT_SERIAL_NUM=24293 AND
3 (QT.AUTH_GROUP_ID=0 OR QT.AUTH_GROUP_ID=1) AND ROWNUM <= 3 ORDER
4 BY TRANSACTION_ID ASC
5 /
Explained.
Elapsed: 00:00:01.00
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 3 | 195 | 17 |
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | VIEW1 | 17 | 1105 | 17 |
|* 3 | SORT ORDER BY STOPKEY | | 17 | 38573 | 17 |
| 4 | NESTED LOOPS | | 17 | 38573 | 10 |
| 5 | MERGE JOIN CARTESIAN | | 1 | 167 | 9 |
| 6 | VIEW | VIEW2 | 1 | 52 | 8 |
| 7 | SORT UNIQUE | | 1 | 156 | 8 |
| 8 | NESTED LOOPS | | 1 | 156 | 6 |
| 9 | NESTED LOOPS | | 1 | 143 | 6 |
| 10 | NESTED LOOPS OUTER | | 1 | 117 | 5 |
|* 11 | HASH JOIN | | 1 | 104 | 5 |
| 12 | NESTED LOOPS | | 1 | 52 | 2 |
|* 13 | TABLE ACCESS FULL | TAB3 | 1 | 39 | 2 |
|* 14 | INDEX UNIQUE SCAN | (PK_TAB4) | 1 | 13 | |
| 15 | TABLE ACCESS FULL | TAB5 | 82 | 4264 | 2 |
| 16 | VIEW PUSHED PREDICATE | View3 | 1 | 13 | |
| 17 | NESTED LOOPS | | 1 | 52 | 2 |
| 18 | NESTED LOOPS | | 1 | 39 | 2 |
|* 19 | INDEX UNIQUE SCAN | (PK_TAB6) | 1 | 13 | 1 |
|* 20 | INDEX RANGE SCAN | (PK_TAB7) | 1 | 26 | 1 |
|* 21 | INDEX UNIQUE SCAN | (PK_TAB8) | 1 | 13 | |
| 22 | TABLE ACCESS BY INDEX ROWID| TAB9 | 3 | 78 | 1 |
|* 23 | INDEX UNIQUE SCAN | (PK_TAB9) | 1 | | |
|* 24 | INDEX UNIQUE SCAN | (PK_TAB10)| 1 | 13 | |
| 25 | BUFFER SORT | | 1 | 115 | 9 |
| 26 | TABLE ACCESS BY INDEX ROWID | TAB2 | 1 | 115 | 1 |
|* 27 | INDEX RANGE SCAN | (TAB2_IDX2)| 1 | | |
|* 28 | TABLE ACCESS BY INDEX ROWID | TAB1 | 12 | 25224 | 1 |
|* 29 | INDEX UNIQUE SCAN | (PK_TAB1) | 1 | | |
Predicate Information (identified by operation id):
1 - filter(ROWNUM<=3)
3 - filter(ROWNUM<=3)
11 - access("TAB5"."PATH_ID"="TAB4"."PATH_ID")
13 - filter("TAB3"."AUTH_GROUP_ID"<>(-1) AND ("TAB3"."AUTH_GROUP_ID"=0 OR "TAB3"."AUTH_GROUP_ID"=1))
14 - access("TAB3"."PATH_ID"="TAB4"."PATH_ID")
19 - access("TAB5"."DOMAIN_ID"="TAB6"."DOMAIN_ID")
20 - access("TAB6"."DOMAIN_ID"="TAB7"."DOMAIN_ID")
21 - access("TAB7"."RULE_ID"="TAB8"."RULE_ID")
23 - access("TAB9"."POLICY_ID"="TAB5"."POLICY_ID")
24 - access("TAB9"."ASSOCIATED_FORM_ID"="TAB10"."FORM_ID")
27 - access("TAB2"."CERT_SERIAL_NUM"=24293)
28 - filter("View2"."POLICY_ID"="TAB1"."POLICY_ID")
29 - access("TAB1"."TRANSACTION_ID"="TAB2"."TRANSACTION_ID")
Note: cpu costing is off
54 rows selected.
Elapsed: 00:00:01.81
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 COLLECTION ITERATOR (PICKLER FETCH) OF 'DISPLAY'
Statistics
39 recursive calls
0 db block gets
629 consistent gets
0 physical reads
104 redo size
5169 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
31 sorts (memory)
0 sorts (disk)
54 rows processed
2) Execution Plan for VIEW1 <<-- With ORDER BY" clause and table alias (order by TAB2.transaction_id)
SQL> explain plan for SELECT TO_CHAR(QT.TRANSACTION_ID), QT.POLICY_ID, QT.REQUEST_TYPE
2 FROM <VIEW1> QT WHERE QT.CERT_SERIAL_NUM=30003 AND
3 (QT.AUTH_GROUP_ID=0 OR QT.AUTH_GROUP_ID=1) AND ROWNUM <= 3 ORDER
4 BY TRANSACTION_ID ASC
5 /
Explained.
Elapsed: 00:00:10.20
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 3 | 195 | 14 |
| 1 | SORT ORDER BY | | 3 | 195 | 14 |
|* 2 | COUNT STOPKEY | | | | |
| 3 | VIEW | VIEW1 | 17 | 1105 | 13 |
| 4 | NESTED LOOPS | | 17 | 38573 | 13 |
| 5 | MERGE JOIN CARTESIAN | | 1 | 167 | 12 |
|* 6 | TABLE ACCESS BY INDEX ROWID | TAB2 | 1 | 115 | 4 |
| 7 | INDEX FULL SCAN | (TAB2_IDX) | 94 | | 1 |
| 8 | BUFFER SORT | | 1 | 52 | 8 |
| 9 | VIEW | VIEW2 | 1 | 52 | 8 |
| 10 | SORT UNIQUE | | 1 | 156 | 8 |
| 11 | NESTED LOOPS | | 1 | 156 | 6 |
| 12 | NESTED LOOPS | | 1 | 143 | 6 |
| 13 | NESTED LOOPS OUTER | | 1 | 117 | 5 |
|* 14 | HASH JOIN | | 1 | 104 | 5 |
| 15 | NESTED LOOPS | | 1 | 52 | 2 |
|* 16 | TABLE ACCESS FULL | TAB3 | 1 | 39 | 2 |
|* 17 | INDEX UNIQUE SCAN | (PK_TAB4) | 1 | 13 | |
| 18 | TABLE ACCESS FULL | TAB5 | 82 | 4264 | 2 |
| 19 | VIEW PUSHED PREDICATE | View3 | 1 | 13 | |
| 20 | NESTED LOOPS | | 1 | 52 | 2 |
| 21 | NESTED LOOPS | | 1 | 39 | 2 |
|* 22 | INDEX UNIQUE SCAN | (PK_TAB6) | 1 | 13 | 1 |
|* 23 | INDEX RANGE SCAN | (PK_TAB7) | 1 | 26 | 1 |
|* 24 | INDEX UNIQUE SCAN | (PK_TAB8) | 1 | 13 | |
| 25 | TABLE ACCESS BY INDEX ROWID| TAB9 | 3 | 78 | 1 |
|* 26 | INDEX UNIQUE SCAN | (PK_TAB9) | 1 | | |
|* 27 | INDEX UNIQUE SCAN | (PK_TAB10) | 1 | 13 | |
|* 28 | TABLE ACCESS BY INDEX ROWID | TAB1 | 12 | 25224 | 1 |
|* 29 | INDEX UNIQUE SCAN | (PK_TAB1) | 1 | | |
Predicate Information (identified by operation id):
2 - filter(ROWNUM<=3)
6 - filter("TAB2"."CERT_SERIAL_NUM"=30003)
14 - access("TAB5"."PATH_ID"="TAB4"."PATH_ID")
16 - filter("TAB3"."AUTH_GROUP_ID"<>(-1) AND ("TAB3"."AUTH_GROUP_ID"=0 OR "TAB3"."AUTH_GROUP_ID"=1))
17 - access("TAB3"."PATH_ID"="TAB4"."PATH_ID")
22 - access("TAB5"."DOMAIN_ID"="TAB6"."DOMAIN_ID")
23 - access("TAB6"."DOMAIN_ID"="TAB7"."DOMAIN_ID")
24 - access("TAB7"."RULE_ID"="TAB8"."RULE_ID")
26 - access("TAB9"."POLICY_ID"="TAB5"."POLICY_ID")
27 - access("TAB9"."ASSOCIATED_FORM_ID"="TAB10"."FORM_ID")
28 - filter("VIEW2"."POLICY_ID"="TAB1"."POLICY_ID")
29 - access("TAB1"."TRANSACTION_ID"="TAB2"."TRANSACTION_ID")
Note: cpu costing is off
53 rows selected.
Elapsed: 00:00:08.29
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 COLLECTION ITERATOR (PICKLER FETCH) OF 'DISPLAY'
Statistics
1079 recursive calls
0 db block gets
597 consistent gets
21 physical reads
0 redo size
5177 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
63 sorts (memory)
0 sorts (disk)
53 rows processed
3) Execution Plan for VIEW1 <<-- Without any "ORDER BY" clause
SQL> explain plan for SELECT TO_CHAR(QT.TRANSACTION_ID), QT.POLICY_ID, QT.REQUEST_TYPE
2 FROM <VIEW1> QT WHERE QT.CERT_SERIAL_NUM=30003 AND
3 (QT.AUTH_GROUP_ID=0 OR QT.AUTH_GROUP_ID=1) AND ROWNUM <= 3 ORDER
4 BY TRANSACTION_ID ASC
5 /
Explained.
Elapsed: 00:00:10.20
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 3 | 213 | 11 |
| 1 | SORT ORDER BY | | 3 | 213 | 11 |
|* 2 | COUNT STOPKEY | | | | |
| 3 | NESTED LOOPS | | 17 | 1207 | 10 |
| 4 | MERGE JOIN CARTESIAN | | 1 | 32 | 9 |
| 5 | VIEW | VIEW2 | 1 | 26 | 8 |
| 6 | SORT UNIQUE | | 1 | 156 | 8 |
| 7 | NESTED LOOPS | | 1 | 156 | 6 |
| 8 | NESTED LOOPS | | 1 | 143 | 6 |
| 9 | NESTED LOOPS OUTER | | 1 | 117 | 5 |
|* 10 | HASH JOIN | | 1 | 104 | 5 |
| 11 | NESTED LOOPS | | 1 | 52 | 2 |
|* 12 | TABLE ACCESS FULL | TAB3 | 1 | 39 | 2 |
|* 13 | INDEX UNIQUE SCAN | PK_TAB4 | 1 | 13 | |
| 14 | TABLE ACCESS FULL | TAB5 | 82 | 4264 | 2 |
| 15 | VIEW PUSHED PREDICATE | VIEW3 | 1 | 13 | |
| 16 | NESTED LOOPS | | 1 | 52 | 2 |
| 17 | NESTED LOOPS | | 1 | 39 | 2 |
|* 18 | INDEX UNIQUE SCAN | PK_TAB6 | 1 | 13 | 1 |
|* 19 | INDEX RANGE SCAN | PK_TAB7 | 1 | 26 | 1 |
|* 20 | INDEX UNIQUE SCAN | PK_TAB8 | 1 | 13 | |
| 21 | TABLE ACCESS BY INDEX ROWID| TAB9 | 3 | 78 | 1 |
|* 22 | INDEX UNIQUE SCAN | PK_TAB9 | 1 | | |
|* 23 | INDEX UNIQUE SCAN | PK_TAB10 | 1 | 13 | |
| 24 | BUFFER SORT | | 1 | 6 | 9 |
| 25 | TABLE ACCESS BY INDEX ROWID | TAB2 | 1 | 6 | 1 |
|* 26 | INDEX RANGE SCAN | TAB2_IDX2 | 1 | | |
|* 27 | TABLE ACCESS BY INDEX ROWID | TAB1 | 12 | 468 | 1 |
|* 28 | INDEX UNIQUE SCAN | PK_TAB1 | 1 | | |
Predicate Information (identified by operation id):
2 - filter(ROWNUM<=3)
10 - access("TAB5"."PATH_ID"="TAB4"."PATH_ID")
12 - filter("TAB3"."AUTH_GROUP_ID"<>(-1) AND ("TAB3"."AUTH_GROUP_ID"=0 OR "TAB3"."AUTH_GROUP_ID"=1))
13 - access("TAB3"."PATH_ID"="TAB4"."PATH_ID")
18 - access("TAB5"."DOMAIN_ID"="TAB6"."DOMAIN_ID")
19 - access("TAB6"."DOMAIN_ID"="TAB7"."DOMAIN_ID")
20 - access("TAB7"."RULE_ID"="TAB8"."RULE_ID")
22 - access("TAB9"."POLICY_ID"="TAB5"."POLICY_ID")
23 - access("TAB9"."ASSOCIATED_FORM_ID"="TAB10"."FORM_ID")
26 - access("TAB2"."CERT_SERIAL_NUM"=1022)
27 - filter("VIEW2"."POLICY_ID"="TAB1"."POLICY_ID")
28 - access("TAB1"."TRANSACTION_ID"="TAB2"."TRANSACTION_ID")
Note: cpu costing is off
52 rows selected.
Elapsed: 00:00:03.37
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 COLLECTION ITERATOR (PICKLER FETCH) OF 'DISPLAY'
Statistics
38 recursive calls
0 db block gets
287 consistent gets
0 physical reads
0 redo size
5006 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
29 sorts (memory)
0 sorts (disk)
52 rows processed -
Sql count function in order by clause
Post Author: krypton
CA Forum: Data Connectivity and SQL
Hi Guys
Can i ask a quick question. I am trying to retrieve data remotely from a SQL Server via crystal reports.
Within the Database Expert I have entered a SQL query to retrive the number of (call center) support calls raised by our customers:-
Select `Primary_Company`, COUNT(`Calls`)From `SPRT_Issue` GROUP BY `Primary_Company`ORDER BY COUNT(`Calls`) desc
The customer's column is called 'Primary Company' and the calls they raise are in the 'Calls' column. the above is a normal sql query.
However Crystal fails to run the query and generates an error message :-
Failed to open a rowset. Details: 420: Driver] Expected lexical element not found: <identifier>
I dont understand why it wont run. In the ORDER BY clause if i replace field 'Calls' by the field 'Primary Company' then it works.
I think the problem is that it wont accept the count function in the order by clause. which is what i want it to do i.e display the calls in descending order by each customer.
Could someone tell me if there is a way around it.
Thanks
KryptonPost Author: krypton
CA Forum: Data Connectivity and SQL
Thanks Lynn
I tried your suggestion. But there is one probelm.
When i sort the data in descending order using the count(calls) field, the data is returned but the customer's name appears multiple times along with their calls raised.
E.g, if customer Mark raised multiple calls i.e. 2, 5, and 10 calls, then the report will show
Mark 2
Mark 5
Mark 10
But is there a way to aggregate all the calls for mark and show them only once:
such as Mark 17
Thanks -
Problem in sql query because of order by clause
Hi All,
I am facing a one problem in my one sql query.I am using Oracle 10gR2.
Query is given below:
SELECT t1.ename
FROM T1, T2
WHERE T1.EMPNO = 1234
AND T1.ACCOUNTNO = T2.ACCOUNTNO
AND T1.SEQ = T2.SEQ
ORDER BY T2.SEQThe Plan of the query is :
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 2 | 218 | 11716 (1)| 00:00:41 |
|* 1 | TABLE ACCESS BY INDEX ROWID | T1 | 1 | 89 | 1 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 2 | 218 | 11716 (1)| 00:00:41 |
|* 3 | TABLE ACCESS BY INDEX ROWID| T2 | 2 | 40 | 11715 (1)| 00:00:41 |
| 4 | INDEX FULL SCAN | PK_T2_SEQ | 58752 | | 122 (5)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | FK_ACCOUNTNO | 3 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------Now i want to reduce the time of this query.
If i am removing Order by clause from query than performance of the query is totally perfect but with order by clause its taking a time.
I have already set SORT_AREA_SIZE but still nothing is improving.
Welcome and thanks for your suggestions.
Thanks,
Edited by: BluShadow on 23-Jun-2011 07:55
added {noformat}{noformat} tags and formatted explain plan to make it readable. Please see {message:id=9360002} for details on how to post code and dataHi,
There are a couple of things I do not understand.
1. Why don't you put {noformat}{noformat} around your code, it makes it so much easier to read, especially your explain plan
2. You claim that the ORDER BY is problematic compared to no order by. Then why do you choose to post only one plan?
3. It is hard to understand how your tables relate, and which indexes you have and which you don't.
- PK_T2_SEQ, does this mean that SEQ alone is primary key of T2?
- If SEQ is primary key of T2, why do you join on accountno, seq and not just seq?
- If SEQ is primary key of T2 one of the tables is denormalized.
4. FK_ACCOUNTNO, is this an index on accountno, alone?
- Or is this AccountNo, Seq?
5. Is there no index on T1.EMPNO?
Above could of course just be a case of my not understanding the names of your indexes.
So, here are my guesses:
Above plan is for the ORDER BY query. That means the optimizer, has chosen to full scan PK_T2_SEQ, since data is then read according to the ORDER BY.
(This could be a bad choice)I
You could try and order by t1.seq, instead. Result should be the same.
Regards
Peter -
Help: PL/SQL passing paramter to ORDER BY clause
I am working on a procedure that using a parameter to pass sorting order. If there parameter, say p_order which is varchar2, can I just use the it directly passing the field name to the order by clause?
What I really want to know is that do I have to use decode together with p_order to achieve the goal?
WJHHi,
The positional notaion in ORDER BY, e.g.
ORDER BY 2, 1is one of the rare cases in which a numeric literal is required. Using an expression, even a bind variable, won't raise an error, but won't sort, either. (It's equivalent to sorting by a constant, which doesn't sort at all.)
Like Centinul said, you have to use dynamic SQL to construct the ORDER BY clause, or use some kind of IF-THEN-ELSE logic (such as CASE), like this:
SELECT ename, sal
FROM scott.emp
ORDER BY CASE
WHEN :x = 1 THEN ename
ELSE TO_CHAR (sal, '000000')
END; -
SQL Query rewrite, remove ORDER BY clause
Hello,
we've just installed a proprietary application which uses an Oracle 11.2.0.2 RAC database. We've seen that one of the auto-generated application's queries
has poor performance (3-5 minutes for results), the query does a SELECT and at the end it uses an ORDER BY clause. If we remove the ORDER BY clause
the query returns the results in less than 5 seconds. Unfortunately, we can't re-write the query in the application since we don't have any access to it and
i was wondering if there is a way to rewrite the specific query from the database.
We've already seen the SQL Patch but we can change only the hints of the query so we can't remove the ORDER BY clause from it. From what we've seen
outlines also change only the hints and not the actual sql statement.
Is there a way to rewrite the specific query from the database ?
thanks in advance,
GiannisMaybe DBMS_ADVANCED_REWRITE can help but this a SQL question than has very likely nothing to do with RAC.
See http://www.oracle-base.com/articles/10g/dbms_advanced_rewrite.php. -
Does anyone know how or where to enter the ORDER BY clause when using a SQL data source in a load rule? I would prefer to do the ordering in the load rule rather than creating a view on the DB side to do this if at all possible.
According to the documentation "The SQL Statement box in the Open SQL Data Sources dialog box provides Select, From, and Where text boxes that help you write SQL queries. You can specify multiple data sources, filter the display of records, and specify how records displayed in Data Prep Editor are ordered and grouped." but I haven't found anywhere where you can order or group data. I don't need to be able group data I just want to be able to order my data to make the load process as efficient as possible.
I do sort the data when inserting it into the load table but Oracle doesn't necessarily insert the records into the table based on their order when going in.
We are currently on Essbase 11.1.1.3 and Oracle 11g.
Any help is greatly apprecied.Well DUH! Everyone knows that! :-)
Not sure why I never tried that, but it works. They need to update the documentation to say this, but we all know that will never happen.
Thanks again! -
Hi All,
I want to order my SELECT using "dynamic ORDER BY". I have a CURSOR (in my PL/SQL procedure) contains a select with ORDER BY clause. I have implemented two combobox in my form (the first contains the column name, the second contains ASC and DESC).I tried with the next:
1) Dynamic ORDER BY in CURSOR with combobox results. IT DOESN'T WORK.
2) Using a block property named "ORDER BY CLAUSE". Here I put, for example, :myBlock.comboColumnOrder. IT DOESN'T WORK.
3) Using a function: set_block_property(myBlock,order_by,:myBlock.comboColumnOrder) or set_block_property(myBlock,default_where,:myBlock.comboColumnOrder). IT DOESN'T WORK.
4) Using dynamic CURSOR: ORACLE FORMS give me an error that said: "...it can't to the CLIENT-SIDE".
I have thought my last solution, but it maybe cumbersome. I do a TEMPORARY TABLE, and my CURSOR insert in this TABLE, and then I'll fetch to my BLOCK.
Thanks a lot.
PS: My ORACLE Version is 10g.PROCEDURE CHEQUEAR_V0 IS
V_ORDEN VARCHAR2(50) := '' || :BLOCK_CHECK.ORDER_BY_NAME || ' ' || :BLOCK_CHECK.ORDER_BY_ASC_DES ;
CURSOR FILA_RESULTADO_TABLA IS
SELECT Last_name,First_name,App_user, App_role, UserDB
FROM adm_users
WHERE
((Last_name IS NULL OR Last_name LIKE '%'||:BLOCK_CHECK.Last_name||'%') AND
(First_name IS NULL OR First_name LIKE '%'||:BLOCK_CHECK.First_name||'%') AND
(App_user IS NULL OR App_user LIKE '%'||:BLOCK_CHECK.App_user||'%') AND
(App_role IS NULL OR App_role LIKE '%'||:BLOCK_CHECK.App_role||'%') AND
(UserDB IS NULL OR UserDB LIKE '%'||:BLOCK_CHECK.User_DB||'%'))
ORDER BY V_ORDEN;
V_Last_name VARCHAR2(50);
V_First_name VARCHAR2(50);
V_App_user VARCHAR2(50);
V_App_role VARCHAR2(50) ;
V_User_DB VARCHAR2(50);
CONT NUMBER ;
BEGIN
CONT := 1 ;
GO_BLOCK('BLOCK_APPS_GRANTS');
CLEAR_BLOCK;
SYNCHRONIZE;
OPEN FILA_RESULTADO_TABLA;
LOOP
FETCH FILA_RESULTADO_TABLA INTO V_Last_name,V_First_name,V_App_user,V_App_role,V_User_DB ;
EXIT WHEN FILA_RESULTADO_TABLA%NOTFOUND;
:BLOCK_APPS_GRANTS.Last_name := V_Last_name ;
:BLOCK_APPS_GRANTS.First_name := V_First_name ;
:BLOCK_APPS_GRANTS.App_user := V_App_user ;
:BLOCK_APPS_GRANTS.App_role := V_App_role ;
:BLOCK_APPS_GRANTS.User_DB := V_User_DB ;
NEXT_RECORD;
CONT := CONT+1;
END LOOP;
IF FILA_RESULTADO_TABLA%ISOPEN THEN
CLOSE FILA_RESULTADO_TABLA;
END IF;
SET_BLOCK_PROPERTY('BLOCK_APPS_GRANTS', ORDER_BY, :BLOCK_CHECK.ORDER_BY_NAME || ' ' || :BLOCK_CHECK.ORDER_BY_ASC_DES);
GO_BLOCK('BLOCK_APPS_GRANTS');
EXECUTE_QUERY;
synchronize;
exception when others then
raise;
END;
Thanks a lot.
Edited by: user11285646 on 22-jul-2009 2:30 -
Is parameter in ORDER BY clause possible?
I'm using a function to return a ref cursor and currently pass a parameter without any problems. I would like to change the sort on the fly by passing a parameter to the order by clause, but Oracle ignores it.
CREATE OR REPLACE PACKAGE pkg_agent_appt_status AS
TYPE rcur IS REF CURSOR;
FUNCTION f_agent_appt_status (ssn IN VARCHAR2, sort_str IN VARCHAR2) RETURN rcur;
END pkg_agent_appt_status;
CREATE OR REPLACE PACKAGE BODY pkg_agent_appt_status AS
FUNCTION f_agent_appt_status (ssn IN VARCHAR2, sort_str IN VARCHAR2)
RETURN rcur
IS
retval rcur;
BEGIN
OPEN retval FOR
SELECT agncy.CORPORATE_NAME "Agency Name",
agnt_state.APPT_STATE "State",
agnt.AGENT_STATUS "Appt Status",
TO_CHAR(agnt_state.APPT_STATE_EFF_DT,'mm/dd/yyyy') "Effective Date",
agnt.AGENT_NUMBER "Agent ID",
agnt.AGENT_STATUS "Agent Status",
STATE.STATE_NAME
FROM AGNT_APPT_STAT_PRDCR_WRK agnt,
AGNT_APPT_STAT_WRK agncy,
AGNT_APPT_STATE_STAT_PRDCR_WRK agnt_state,
STATE
WHERE agnt.AGENT_TAX_ID = ssn
AND agnt.COMPANY_CODE = agncy.COMPANY_CODE
AND agnt.PARENT_AGENT_AGENCY_ID = agncy.AGENT_NUMBER
AND agnt.COMPANY_CODE = agnt_state.COMPANY_CODE
AND agnt.AGENT_AGENCY_ID = agnt_state.AGENT_AGENCY_ID
AND agnt.AGENT_NUMBER = agnt_state.AGENT_NUMBER
AND agnt_state.APPT_STATE = STATE.STATE_CODE
ORDER BY
sort_str;
RETURN retval;
END f_agent_appt_status;
END pkg_agent_appt_status;If you want to do this, you'd have to use dynamic SQL (execute immediate or DBMS_SQL). For the easier 'execute immediate' approach, you'd do something like
create or replace someProc( someArg varchar2 )
as
strSQL varchar2(4000)
begin
strSQL := <<string containing your SQL statement up to the order by clause>>
strSQL := strSQL || 'ORDER BY ' || someArg
execute immediate strSQL;
endJustin
Maybe you are looking for
-
Data Usage - How much data is what???
I recently looked at my college freshman's data usage on our bill and was stunned to see the almost Incessant data usage at least 5 or 6 times every hour, even throughout the night. How can I tell if its her Droid collecting data when she isn't using
-
How to drag a selection of text in RichTextEditor ?
I don't know if there is any way to drag a selection of text ? I struggle with this for one day now . I want to let the user drag their text selection to a datagrid or canvas , but when I select a part of text ,the sencod time I trigger mousedown eve
-
SQL Query issue with large varchar column
I have a SQL Query (PL/SQL function body returning SQL query) which contains a large varchar column. Even if I substring the column to 30chars when it displays on the page it wraps. I have tried putting nowrap="wrap" for the HTML table cell attribute
-
I can't import MS Word X for Mac files into PageMaker (7.0). When I save them as Word 5.1 files I can, sort of, but the upper level ASCII characters get all screwed up, I lose all style, italics, superscript, and so forth. I haven't been able to find
-
CUIS / CUIC Custom Reporting Summary
I am using Cisco CUIS versiopn 7.5.(4) I have been able to successfully add a new reporting field in CUIS using the formula editor. Here is the formula: [RowField]/Sum([RowField]) Gives me a percent of the total of the entire report. This report