Мне нужен запрос вроде
select id,name from sample
where
(:test IS NULL
OR name IN (:test))
)
Это возможно? Я не хочу использовать внутренние запросы.
Я хочу отфильтровать запрос, используя параметр запроса: тест, который представляет собой значения, разделенные запятыми. Например, у меня есть столбец имен со значениями ex1, ex2, ex3. Мне нужно получить все идентификаторы и имена из таблицы, где имена находятся в ('ex1', 'ex2'). Итак, на выходе будут две строки с именами ex1 и ex2.
независимо от того, имеет ли: test значение null или имя в (: test), он выдаст все строки !!!
Возможный дубликат Передача значения, разделенного запятыми, в качестве параметра IN в хранимой процедуре


Попробуйте этот запрос:
SELECT id, name
FROM sample
WHERE :test LIKE CONCAT('%,', CONCAT(name, ',%'));
вы не можете использовать listagg в IN, потому что для сопоставления требуется результирующий набор только одного столбца, который не будет работать. попробуйте простой:
select id,name from sample
where :test is null or
:test in (select name from sample);
из предложения where вашего, похоже, вам понадобится только все идентификаторы, имена из таблицы. независимо от того, имеет ли: test значение null или имя в (: test), он выдаст все строки !!!
Вы должны создать некоторую табличную функцию "строковый токенизатор". Это может быть полезно и для других алгоритмов.
create function regexp_tokenize(
source clob(2M)
, pattern varchar(128))
returns table (seq int, tok varchar(4000))
contains sql
deterministic
no external action
return
select seq, tok
from xmltable('for $id in tokenize($s, $p) return <i>{string($id)}</i>'
passing
source as "s"
, pattern as "p"
columns
seq for ordinality
, tok varchar(4000) path '.'
) t;
Теперь мы можем сделать следующее:
with sample (id, name) as (values
(1, 'ex1')
,(2, 'ex2')
,(3, 'ex3')
)
select s.*
from sample s
join table(regexp_tokenize(coalesce('ex1,ex2', s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(cast(null as varchar(10)), s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(:test, s.name), ',')) f on f.tok=s.name
;
На самом деле, из соображений производительности лучше создавать разные операторы для ввода NULL и NOT NULL.
Пожалуйста, включите некоторые образцы данных, которые помогут объяснить ваш вопрос. Я не слежу за тем, что вы здесь пытаетесь сделать.