Discussions
Categories
- 196.9K All Categories
- 2.2K Data
- 239 Big Data Appliance
- 1.9K Data Science
- 450.4K Databases
- 221.7K General Database Discussions
- 3.8K Java and JavaScript in the Database
- 31 Multilingual Engine
- 550 MySQL Community Space
- 478 NoSQL Database
- 7.9K Oracle Database Express Edition (XE)
- 3K ORDS, SODA & JSON in the Database
- 546 SQLcl
- 4K SQL Developer Data Modeler
- 187.1K SQL & PL/SQL
- 21.3K SQL Developer
- 295.9K Development
- 17 Developer Projects
- 138 Programming Languages
- 292.6K Development Tools
- 107 DevOps
- 3.1K QA/Testing
- 646K Java
- 28 Java Learning Subscription
- 37K Database Connectivity
- 155 Java Community Process
- 105 Java 25
- 22.1K Java APIs
- 138.1K Java Development Tools
- 165.3K Java EE (Java Enterprise Edition)
- 18 Java Essentials
- 160 Java 8 Questions
- 86K Java Programming
- 80 Java Puzzle Ball
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 94.3K Java SE
- 13.8K Java Security
- 204 Java User Groups
- 24 JavaScript - Nashorn
- Programs
- 443 LiveLabs
- 38 Workshops
- 10.2K Software
- 6.7K Berkeley DB Family
- 3.5K JHeadstart
- 5.7K Other Languages
- 2.3K Chinese
- 171 Deutsche Oracle Community
- 1.1K Español
- 1.9K Japanese
- 232 Portuguese
I need help on lexical parameter in cursor

Dear Experts,
Hope you are fine.
I'm using oracle DB 10.1.2 and forms 10.1.2.3. I want to write a cursor where "few where condition" may exist or not exist.
Like bellow are the main cursor SQL.
SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND DEPT_ID=:P1 AND DIVM_ID=:P2 ORDER BY BDATE;
Here i want, user may pass the value of P1,P2 or any one or none. With more information. B_DATE and E_DATE must entered by user and
If user pass the both value of P1 and P2 then the above sql is ok for cursor. but if user don't pass the valu of P1 then cursor sql should like
SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND DIVM_ID=:P2 ORDER BY BDATE;
How i do this in one cursor ?
Thanks for your time.
Ask2Learn
Best Answer
-
Hi,
You could write the SQL as below...
SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND (DEPT_ID=:P1 OR :P1 is NULL) AND (DIVM_ID=:P2 OR :P2 is NULL) ORDER BY BDATE;
This way if P1 is not entered by user then it will be null (same for P2).
Hope this helps.
vr,
Sudhakar
Answers
-
Hi,
You could write the SQL as below...
SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND (DEPT_ID=:P1 OR :P1 is NULL) AND (DIVM_ID=:P2 OR :P2 is NULL) ORDER BY BDATE;
This way if P1 is not entered by user then it will be null (same for P2).
Hope this helps.
vr,
Sudhakar
-
Sometimes supervisors don't want to see or among predicates
SELECT TEMP_DATA
FROM TAB1
WHERE BDATE BETWEEN :B_DATE AND :E_DATE
AND DEPT_ID = NVL(:P1,DEPT_ID)
AND DIVM_ID = NVL(:P2,DIVM_ID)
ORDER BY BDATE
Regards
Etbin
-
Etbin wrote: Sometimes supervisors don't want to see or among predicates SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND DEPT_ID = NVL(:P1,DEPT_ID) AND DIVM_ID = NVL(:P2,DIVM_ID) ORDER BY BDATE
Regards EtbiHI Etbin
In my own practice I found that
:P1 is null or column = :P1 faster than column = nvl(:P1,column)
i think it is faster because short circuit is working ... But I would like to note that it is only my opinion and not documented
----
Ramin Hashimzade
-
Sudhakar_B wrote: Hi, You could write the SQL as below...
- SELECT TEMP_DATA
- FROM TAB1
- WHERE BDATE BETWEEN :B_DATE AND :E_DATE
- AND (DEPT_ID=:P1 OR :P1 is NULL)
- AND (DIVM_ID=:P2 OR :P2 is NULL)
- ORDER BY BDATE;
SELECT TEMP_DATA FROM TAB1 WHERE BDATE BETWEEN :B_DATE AND :E_DATE AND (DEPT_ID=:P1 OR :P1 is NULL) AND (DIVM_ID=:P2 OR :P2 is NULL) ORDER BY BDATE;
This way if P1 is not entered by user then it will be null (same for P2). Hope this helps. vr, Sudhakar
Thanks Sudhakar. It's work like a charm.
-
I'm making no claims. It just occurred to me that from time to time I have to deal with stereotypes like this (and the OP might too)
Regards
Etbin
-
Thanks Etbin, Ramin,
We are all victims of profiling (I mean performance related) from time to time. One thing I have come to firmly believe, over years is that, Oracle Optimizer for the most part is way more intelligent than me ;-)
Got my 12c test DB few days back and tried this scenario out.
In my very limited testing it seems column = nvl(:P1,column) performs better than :P1 is null or column = :P1 (From explain plan and consistent gets perspective)
Moral of the story is as far as performance in Oracle is concerned, for your specific case test it out o find what works better!!!
Also,
With column = nvl(:P1,column) construct Oracle 12c builds and access path using TABLE ACCESS BY INDEX ROWID BATCHED operation. I guess this new in 12c. Need to read more about this.
SQL> select * from v$version; Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production SQL> SQL> set autotrace traceonly statistics explain; SQL> set timing on; SQL> set line 200; SQL> SQL> var e1 number; SQL> -- E1 is null SQL> select * from employees 2 where employee_id = :e1 OR :e1 is null; 107 rows selected. Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 1445457117 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 6 | 414 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMPLOYEES | 6 | 414 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(:E1 IS NULL OR "EMPLOYEE_ID"=TO_NUMBER(:E1)) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 15 consistent gets 0 physical reads 0 redo size 10121 bytes sent via SQL*Net to client 621 bytes received via SQL*Net from client 9 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 107 rows processed SQL> SQL> select * from employees 2 where employee_id = nvl( :e1 ,employee_id); 107 rows selected. Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 929977954 ------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 108 | 7452 | 0 (0)| 00:00:01 | | 1 | CONCATENATION | | | | | | |* 2 | FILTER | | | | | | | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES | 107 | 7383 | 0 (0)| 00:00:01 | |* 4 | INDEX FULL SCAN | EMP_EMP_ID_PK | 107 | | 0 (0)| 00:00:01 | |* 5 | FILTER | | | | | | | 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES | 1 | 69 | 0 (0)| 00:00:01 | |* 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(:E1 IS NULL) 4 - filter("EMPLOYEE_ID" IS NOT NULL) 5 - filter(:E1 IS NOT NULL) 7 - access("EMPLOYEE_ID"=:E1) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 19 consistent gets 0 physical reads 0 redo size 10121 bytes sent via SQL*Net to client 621 bytes received via SQL*Net from client 9 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 107 rows processed SQL> SQL> -- E1 is 10 KNOWN to be not found; SQL> begin :e1 := 10; end; 2 / PL/SQL procedure successfully completed. Elapsed: 00:00:00.00 SQL> SQL> select * from employees 2 where employee_id = :e1 OR :e1 is null; no rows selected Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 1445457117 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 6 | 414 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMPLOYEES | 6 | 414 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(:E1 IS NULL OR "EMPLOYEE_ID"=TO_NUMBER(:E1)) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 7 consistent gets 0 physical reads 0 redo size 1061 bytes sent via SQL*Net to client 533 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed SQL> SQL> select * from employees 2 where employee_id = nvl( :e1 ,employee_id); no rows selected Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 929977954 ------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 108 | 7452 | 0 (0)| 00:00:01 | | 1 | CONCATENATION | | | | | | |* 2 | FILTER | | | | | | | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES | 107 | 7383 | 0 (0)| 00:00:01 | |* 4 | INDEX FULL SCAN | EMP_EMP_ID_PK | 107 | | 0 (0)| 00:00:01 | |* 5 | FILTER | | | | | | | 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES | 1 | 69 | 0 (0)| 00:00:01 | |* 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(:E1 IS NULL) 4 - filter("EMPLOYEE_ID" IS NOT NULL) 5 - filter(:E1 IS NOT NULL) 7 - access("EMPLOYEE_ID"=:E1) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 1 consistent gets 0 physical reads 0 redo size 1061 bytes sent via SQL*Net to client 533 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed SQL> SQL> -- E1 is 107 KNOWN to be found; SQL> begin :e1 := 107; end; 2 / PL/SQL procedure successfully completed. Elapsed: 00:00:00.00 SQL> SQL> select * from employees 2 where employee_id = :e1 OR :e1 is null; Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 1445457117 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 6 | 414 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMPLOYEES | 6 | 414 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(:E1 IS NULL OR "EMPLOYEE_ID"=TO_NUMBER(:E1)) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 8 consistent gets 0 physical reads 0 redo size 1323 bytes sent via SQL*Net to client 544 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> SQL> select * from employees 2 where employee_id = nvl( :e1 ,employee_id); Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 929977954 ------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 108 | 7452 | 0 (0)| 00:00:01 | | 1 | CONCATENATION | | | | | | |* 2 | FILTER | | | | | | | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES | 107 | 7383 | 0 (0)| 00:00:01 | |* 4 | INDEX FULL SCAN | EMP_EMP_ID_PK | 107 | | 0 (0)| 00:00:01 | |* 5 | FILTER | | | | | | | 6 | TABLE ACCESS BY INDEX ROWID | EMPLOYEES | 1 | 69 | 0 (0)| 00:00:01 | |* 7 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(:E1 IS NULL) 4 - filter("EMPLOYEE_ID" IS NOT NULL) 5 - filter(:E1 IS NOT NULL) 7 - access("EMPLOYEE_ID"=:E1) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 2 consistent gets 0 physical reads 0 redo size 1323 bytes sent via SQL*Net to client 544 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL>
vr,
Sudhakar