Игнорировать параметр диапазона дат в предложении where, если параметр не введен - PullRequest
0 голосов
/ 26 июня 2019

Игнорировать параметр диапазона дат в предложении where, если параметр не введен.Для моего диапазона дат я использую Between.

Эти параметры вводятся из отчета яшмы

SELECT * 
  from customer 
 where client_id = $P{CLIENT_ID} 
   AND (Account_id = CASE WHEN $P{Account_ID}>0 
                          THEN $P{Account_ID} 
                          ELSE Account_ID END 
        OR Account_ID IS NULL ) 
   AND datetrx BETWEEN $P{DATE_START} AND $P{DATE_END} 

, если дата не указана, в отчете должны быть записи любых дат, поскольку диапазон дат не введен

1 Ответ

0 голосов
/ 26 июня 2019

У вас есть две возможности приблизиться к необязательным параметрам ввода.

Более простой способ состоит в использовании статического SQL и предоставлении значения default для отсутствующих параметров, поэтомучто вы получаете все совпадения.

Здесь вы просто устанавливаете границы минимальной и максимально возможной ДАТЫ.

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

Более продвинутый продвинутый способ был популяризирован 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)

Оба оператора дают разныеплан выполнения, оптимизированный для входного параметра.В статическом параметре необходимо использовать один и тот же план выполнения для всех входных данных, которые могут вызвать проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...