Имате две възможности за подход към незадължителните входни параметри.
По-простото начин е да използвате статичен SQL и да предоставите по подразбиране стойност за липсващите параметри, така че да получите всички съвпадения.
Тук просто задавате границите на минималната и максималната възможна ДАТА.
select *
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between nvl($P{DATE_START},date'1900-01-01')
and nvl($P{DATE_END},date'2200-01-01')
Колкото по-напреднали way е популяризиран от Tom Kyte и се основава на използването на динамичен SQL.
Ако параметрите са предоставени , генерирате нормален SQL с BETWEEN
предиката :
select *
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between $P{DATE_START} and $P{DATE_END}
В случай, че параметърът липсва (т.е. NULL
се предава) генерирате различен SQL както е показано по-долу.
select *
from customer
where customer_id = $P{CLIENT_ID}
and (1=1 or datetrx between $P{DATE_START} and $P{DATE_END})
Имайте предвид, че
1) броят на свързващите променливи е еднакъв и в двата варианта на заявката, което е важно, тъй като можете да използвате идентичен setXXXX
изявления
2) поради прекия път 1 = 1 or
е between
предикатът се игнорира, т.е. всички дати се вземат предвид.
Коя опция трябва да се използва?
Е, за прости заявки ще има малка разлика, но за сложни заявки с няколко опции за липсващи параметри и големи данни, динамичният SQL подход е предпочитан .
Причината е, че с помощта на статичен SQL използвате едно и също изявление за повече различни заявки - тук една за достъп с диапазон от данни и един за достъп без диапазон от данни.
Динамичната опция създава различен SQL за всеки достъп.
Може да го видите в плановете за изпълнение:
Достъп с период от време
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 1 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | INDEX RANGE SCAN| CUST_IDX1 | 1 | 22 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE(:1)<=TO_DATE(:2))
2 - access("CUSTOMER_ID"=1 AND "DATETRX">=:1 AND "DATETRX"<=:2)
Достъп без обхват на данни
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| CUST_IDX1 | 1 | 22 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("CUSTOMER_ID"=1)
И двата оператора произвеждат различен план за изпълнение, който е оптимизиран за входния параметър. При статичната опция използването трябва да споделя един и същ план за изпълнение за всички въведени данни, които могат да причинят проблеми.