Máte dvě možnosti, jak přistoupit k volitelným vstupním parametrům.
Jednodušší způsob je použít statické SQL a poskytnout výchozí hodnotu pro chybějící parametry, abyste získali všechny shody.
Zde jednoduše nastavíte hranice na minimální a maximální možné DATUM.
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')
Čím více pokročilých way byl popularizován Tomem Kytem a je založen na použití dynamického SQL.
Pokud jsou uvedeny parametry , vygenerujete normální SQL pomocí BETWEEN
predikát :
select *
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between $P{DATE_START} and $P{DATE_END}
V případě, že chybí parametr (tj. NULL
je předán) vygenerujete jiné SQL jak je uvedeno níže.
select *
from customer
where customer_id = $P{CLIENT_ID}
and (1=1 or datetrx between $P{DATE_START} and $P{DATE_END})
Všimněte si, že
1) počet proměnných vazby je stejný v obou variantách dotazu, což je důležité, protože můžete použít identické setXXXX
prohlášení
2) kvůli zkratce 1 = 1 or
je between
predikát ignorován, tj. všechna data jsou brána v úvahu.
Kterou možnost použít?
U jednoduchých dotazů bude malý rozdíl, ale u složitých dotazů s několika možnostmi chybějících parametrů a velkých dat je upřednostňován dynamický SQL přístup .
Důvodem je, že při použití statického SQL použijete stejný příkaz pro více různých dotazů – zde jeden pro přístup s datový rozsah a jeden pro přístup bez datový rozsah.
Dynamická volba vytváří různé SQL pro každý přístup.
Můžete to vidět na prováděcích plánech:
Přístup s časovým obdobím
-------------------------------------------------------------------------------
| 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)
Přístup bez datového rozsahu
------------------------------------------------------------------------------
| 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)
Oba příkazy vytvářejí odlišný plán provádění, který je optimalizován pro vstupní parametr. Ve statické možnosti použití musí sdílet stejný plán provádění pro všechny vstupy, které mohou způsobit problémy.