2017-02-13 18 views
1

Есть ли довольно простой способ ввода входного параметра, содержащего разделенный запятыми список префиксов и возвращающий курсор на основе оператора select, который их использует?PL/SQL Хранимый proc, который использует параметр, разделенный запятой, для управления динамическим предложением LIKE?

т.е. (псевдокод)

PROCEDURE get_by_prefix(p_list_of_prefixes IN varchar2, r_csr OUT SYS_REFCURSOR) 
IS 
BEGIN 
OPEN r_csr FOR 
SELECT * FROM my_table where some_column LIKE (the_individual_fields_from p_list_of_prefixes ||'%') 
END 

Я пробовал различные комбинации, и теперь есть две проблемы - принуждая вход в подходящую таблицу (я думаю, что она должна идти в тип таблицы, а не VARCHAR2_TABLE), и, во-вторых, получение подобной статьи для эффективного SELECT из внутреннего «псевдоустойчивого» ...

EDIT: Кажется, люди предлагают способы использовать «IN» с набором потенциальных значений, тогда как Im look при использовании LIKE. I может использовать, используя подобную технику - создание динамического SQL, но было интересно, нет ли более элегантного способа ...

+0

Это не работает с LIKE, если только я не ошибаюсь .... – PaulJWilliams

+0

Возможный дубликат параметра [разделенный запятой в хранимой процедуре plsql] (http://stackoverflow.com/questions/28159341/comma-separated-parameter-in- plsql-stored-procedure) – XING

+0

Вы пытаетесь использовать 'like' как' In', и оба предназначены для некоторых целей. Если бы оба были одинаковыми, то не было бы необходимости в двух разных операторах. – XING

ответ

0

PL/SQL не имеет понятия разделенного запятой списка и не имеет встроенного сплиттера, поскольку в Perl и т.д., так что вы должны будете использовать один из самодельных методов, такие, как этот:

https://stewashton.wordpress.com/2016/08/01/splitting-strings-surprise

(Other methods доступны.) Тогда это просто вопрос либо заселения коллекции в одном шаг и использование его в следующем, или же объединение этих двух типов:

declare 
    p_list_of_prefixes varchar2(100) := 'John,Jim,Jules,Janice,Jenny'; 
begin 
    open :refcur for 
     with params as 
      (select x.firstname 
       from xmltable(
          'ora:tokenize($X, "\,")' 
          passing p_list_of_prefixes as x 
          columns firstname varchar2(4000) path '.' 
        ) x 
      ) 
      , people as 
      (select 'Dave Clark' as fullname from dual union all 
       select 'Jim Potter' from dual union all 
       select 'Jenny Jones' from dual 
      ) 
     select x.firstname, p.fullname 
     from params x 
       left join people p on p.fullname like x.firstname || '%'; 
end; 

Выход:

FIRSTNAME  FULLNAME 
-------------- ----------- 
John   
Jim   Jim Potter 
Jules   
Janice   
Jenny   Jenny Jones 
0

Используя LIKE, как вы хотите легко, но это неправильное решение. (См. Мой комментарий под оригинальным сообщением).

В любом случае - если по приказу начальства, или какой-либо другой пол-уважительной причиной, вы должны использовать LIKE условие, это должно выглядеть примерно так:

... where ',' || p_list_of_whatever || ',' like '%,' || some_column || ',% 

конкатенация запятые на обоих концах обе стороны сравнения необходимы, потому что вы не хотите, чтобы Jo в столбце соответствовал John во входном списке. Начните оттуда, и вы увидите, почему вам нужны запятые справа, а затем следуйте оттуда, и вы увидите, почему они нужны вам и слева.