Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Zignoruj ​​parametr zakresu dat w klauzuli WHERE, gdy parametr nie jest wprowadzony

Masz dwie możliwości podejścia do opcjonalnych parametrów wejściowych.

prostsze sposobem jest użycie statycznego SQL i podanie domyślnego wartość dla brakujących parametrów, aby uzyskać wszystkie dopasowania.

Tutaj po prostu ustawiasz granice na minimalną i maksymalną możliwą datę.

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

Im bardziej zaawansowany sposób został spopularyzowany przez Toma Kyte i opiera się na wykorzystaniu dynamicznego SQL.

Jeśli parametry są podane , generujesz normalny kod SQL z BETWEEN orzeczenie :

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

W przypadku braku parametru (np. NULL jest przekazany) generujesz inny kod SQL jak pokazano poniżej.

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

Zwróć uwagę, że

1) liczba zmiennych wiązania jest taka sama w obu wariantach zapytania, co jest ważne, ponieważ możesz użyć identycznego setXXXX oświadczenia

2) ze względu na skrót 1 = 1 or jest between predykat ignorowany, tj. wszystkie daty są brane pod uwagę.

Której opcji należy użyć?

Cóż, w przypadku prostych zapytań będzie niewielka różnica, ale w przypadku złożonych zapytań z kilkoma opcjami brakujących parametrów i dużymi danymi, preferowane jest dynamiczne podejście SQL .

Powodem jest to, że używając statycznego SQL, używasz tej samej instrukcji dla większej liczby różnych zapytań - tutaj jedno dla dostępu za pomocą zakres danych i jeden dla dostępu bez zakres danych.

Opcja dynamiczna generuje inny kod SQL dla każdego dostępu.

Możesz to zobaczyć na planach wykonania:

Dostęp z zakresem dat

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

Dostęp bez zakresu danych

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

Obie instrukcje tworzą inny plan wykonania, który jest zoptymalizowany pod kątem parametru wejściowego. W opcji statycznej użycie musi współdzielić ten sam plan wykonania dla wszystkich danych wejściowych, które mogą powodować problemy.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstaw obiekt BLOB w bazie danych Oracle za pomocą C#

  2. nhibernate, wywołaj funkcję w Oracle, która zwraca refcursor sys

  3. Podziel varchar na oddzielne kolumny w Oracle

  4. Zablokuj bazę danych Oracle przed uruchomieniem skryptów usuwania/ładowania danych

  5. Jak nadać unikalne ograniczenie kombinacji kolumn w Oracle?