sql >> Database teknologi >  >> RDS >> Oracle

Ignorer datointervalparameteren i where-udtrykket, når parameteren ikke er indtastet

Du har to muligheder for at nærme dig de valgfri inputparametre.

Det enklere måde er at bruge statisk SQL og give standard værdi for de manglende parametre, så du får alle matches.

Her sætter du ganske enkelt grænserne til den minimale og maksimale mulige DATO.

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')
 

Jo mere avanceret måde blev populariseret af Tom Kyte og er baseret på brug af dynamisk SQL.

Hvis parametrene er angivet , genererer du normal SQL med BETWEEN prædikat :

select * 
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between $P{DATE_START} and $P{DATE_END}
 

I tilfælde af at parameteren mangler (dvs. NULL er bestået) genererer du en anden SQL som vist nedenfor.

select * 
from customer
where customer_id = $P{CLIENT_ID}
and (1=1 or datetrx between $P{DATE_START} and $P{DATE_END})
 

Bemærk, at

1) antallet af bindevariablerne er det samme i begge varianter af forespørgslen, hvilket er vigtigt, da du kan bruge identiske setXXXX udsagn

2) på grund af genvejen 1 = 1 or er between prædikat ignoreret, dvs. alle datoer tages i betragtning.

Hvilken mulighed skal bruges?

For simple forespørgsler vil der være små forskelle, men for komplekse forespørgsler med flere muligheder for manglende parametre og store data er den dynamiske SQL-tilgang at foretrække .

Årsagen er, at ved brug af statisk SQL bruger du den samme sætning til flere forskellige forespørgsler - her en for adgang med dataområde og et til adgang uden dataområde.

Den dynamiske indstilling producerer forskellig SQL for hver adgang.

Du kan muligvis se det på udførelsesplanerne:

Adgang med datointerval

------------------------------------------------------------------------------- | 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)

Adgang uden datainterval

------------------------------------------------------------------------------ | 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)

Begge udsagn producerer forskellige udførelsesplaner, der er optimeret til inputparameteren. I den statiske mulighed skal brug dele den samme udførelsesplan for alle input, der kan forårsage problemer.




  1. Hurtigste måde at opdatere 120 millioner poster på

  2. Bindestreger i kolonnenavne i MySQL DB

  3. postgresql udenlandsk nøgle syntaks

  4. Sådan bruger du Case Statement til betinget formatering i Select Query - SQL Server / TSQL Tutorial Del 116