Oracle
 sql >> база данни >  >> RDS >> Oracle

Игнорирайте параметъра за период от време в клаузата where, когато параметърът не е въведен

Имате две възможности за подход към незадължителните входни параметри.

По-простото начин е да използвате статичен 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)

И двата оператора произвеждат различен план за изпълнение, който е оптимизиран за входния параметър. При статичната опция използването трябва да споделя един и същ план за изпълнение за всички въведени данни, които могат да причинят проблеми.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Относно елемента за формат RM в Oracle

  2. Как да получа текстово съдържание от BLOB в Oracle SQL

  3. Списък с външни ключове и таблиците, към които се отнасят в Oracle DB

  4. Oracle.DataAccess.dll не може да бъде намерен, въпреки че съществува

  5. Sql:разлика между две дати