Oracle Java - добавить необязательный параметр даты в подготовленную выписку - PullRequest
0 голосов
/ 05 апреля 2020

Я хочу добавить необязательный параметр "todate" в подготовленный оператор

Один из способов - добавить заполнитель для необязательного параметра (ов) и заменить его перед выполнением

  where id=? OPTIONAL_SECTION 

Например, Для OPTIONAL_SECTION будет задано значение TO_DATE <= sysdate -1 </p>

Лучший и правильный способ - связать необязательный параметр с обработкой нуля

where id=? and TO_DATE <= nvl(?, TO_DATE)

Есть ли лучший способ обработки необязательного параметра даты? Тем более что условие может быть без равных (TO_DATE <?) </p>

  • Это минимальный пример, Id не является первичным ключом (на самом деле это внешний ключ), SQL возвращает несколько записей

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Лучший и правильный способ - связать необязательный параметр с обработкой нуля

Это не обязательно лучше или более правильно. Это другой способ, но очень спорный, если он «лучше и (более) правильный».

SQL Оптимизаторы запросов обычно запускаются до того, как станут известны любые значения аргумента ?, поэтому TO_DATE <= nvl(?, TO_DATE) не может быть оптимизирован и потребует полного сканирования таблицы, исключая любые другие условия в предложении where.

Однако с TO_DATE <= ? оптимизатор может использовать индекс для TO_DATE для выполнения сканирование индекса по дальности, поэтому я бы сказал, что первый вариант потенциально лучше, в зависимости от доступных индексов.


условие может быть без равных (TO_DATE <?) </p>

Правильный способ написания второй версии:

where id = ?
  and (? is null or TO_DATE < ?)

Тогда вам, конечно, придется дважды указать значение для PreparedStatement.

0 голосов
/ 05 апреля 2020

Первое решение для запроса с необязательным параметром выглядит следующим образом:

1) допустимо ли использование одного оператора для обеих / всех опций

2) предпочтительно использовать отдельное утверждение для каждой опции

В вашем случае у вас есть две опции параметров:

id

id и date_parameter

Исходя из именования, я бы сказал, что ID является первичным ключом таблицы, поэтому он возвращает только одну строку и будет драйвером в плане выполнения - простой доступ к индексу .

. date_parameter может привести только к тому, что запрос вернет без строки

В этом случае вы можете смело использовать решение 1) - один запрос для обоих вариантов будет приемлемым

Но в другой интерпретации ID является внешним ключом с тоннами строк и date_parameter используется для возврата только небольшого числа последних строк.

В этом случае решение 1) aka O R-запрос плохо завершится . План выполнения оптимизирован для случая, возвращающего массовые данные, поэтому вы будете ждать целую вечность, чтобы получить несколько строк.

Так что в этом случае только решение 2) обеспечивает эффективное решение. Краткий ответ заключается в динамической генерации двух запросов на основе переданного параметра

where id=? 

where id=? and data_parameter <= ?

Техническая проблема в этом подходе заключается в том, что запросы имеют разное количество переменных связывания. , что делает setXXX сложным.

Чтобы избежать этой проблемы, вы можете использовать трюк 1=1 or, который а) делает число переменной связывания равным во всех запросах * и б) устраняет ненужное onces.

Запрос только для ID генерируется как

where id=? and 1=1 or data_parameter <= ?

Запрос с ID и DATE_PARAM остается таким же

where id=? and data_parameter <= ? 

Еще несколько примеров и кредит для популяризации этого подхода может быть foud здесь и там

...