В вашей версии Oracle вы можете применить некоторые хитрости к вашему запросу, чтобы сделать это.Идея состоит в том, чтобы использовать запрос в следующей форме:
select *
from
(select
:possibleParam1 as param1
-- do the same for every possible param in your query
:possibleParamN as paramN
from dual
where rownum > 0) params
inner join
-- join your tables here
on
-- concatenate your filters here
where
-- fixed conditions
, а затем выполнить его с помощью:
open c for query using param1, ..., paramN;
Он работает с использованием DUAL
для создания поддельной строки с каждымparam, затем внутреннее соединение этой фиктивной строки с вашим реальным запросом (без каких-либо фильтров), используя только те фильтры, которые вы хотите применить.Таким образом, у вас есть фиксированный список переменных связывания в списке SELECT
подзапроса params
, но вы можете контролировать, какие фильтры применяются, изменяя условие соединения между params
и вашим реальным запросом.
Итак, если у вас есть что-то вроде, скажем:
create table people (
first_name varchar2(20)
last_name varchar2(20)
);
, вы можете построить следующий запрос, если вы просто хотите фильтровать по first name
select *
from
(select
:first_name as first_name,
:last_name as last_name
from dual
where rownum > 0) params
inner join
people
on
people.first_name = params.first_name;
, и это, если вы хотитефильтровать как first_name
, так и last_name
select *
from
(select
:first_name as first_name,
:last_name as last_name
from dual
where rownum > 0) params
inner join
people
on
people.first_name = params.first_name and
people.last_name = params.last_name;
, и в каждом случае вы выполняете с
open c for query using filterFirstName, filterLastName;
Для производительности важно использовать where rownum > 0
с DUAL
, поскольку это заставляет Oracle «материализовать» подзапрос.Это обычно заставляет DUAL
прекратить вмешиваться в остальную часть запроса.В любом случае, вам следует проверить планы выполнения, чтобы убедиться, что Oracle не делает ничего плохого.