Как извлечь шаблон из таблицы в Oracle 11g? - PullRequest
1 голос
/ 22 июня 2011

Я хочу извлечь текст из столбца, используя регулярные выражения в Oracle 11g.У меня есть 2 запроса, которые делают работу, но я ищу (чище / приятнее) способ сделать это.Возможно объединение запросов в один или новый эквивалентный запрос.Вот они:

Запрос 1: определить строки, соответствующие шаблону:

select column1 from table1 where regexp_like(column1, pattern);

Запрос 2: извлечь весь сопоставленный текст из соответствующей строки.

select regexp_substr(matching_row, pattern, 1, level) 
from dual
connect by level < regexp_count(matching_row, pattern);

Я использую PL / SQL, чтобы склеить эти два запроса, но это грязно и неуклюже.Как я могу объединить их в 1 запрос.Спасибо.

ОБНОВЛЕНИЕ: пример данных для шаблона 'BC':

row 1: ABCD
row 2: BCFBC
row 3: HIJ
row 4: GBC

Ожидаемый результат - таблица из 4 строк 'BC'.

Ответы [ 2 ]

1 голос
/ 23 июня 2011

Вы также можете сделать это одним запросом, функции / процедуры / пакеты не требуются:

WITH t1 AS (
SELECT 'ABCD' c1 FROM dual
UNION
SELECT 'BCFBC' FROM dual
UNION
SELECT 'HIJ' FROM dual
UNION
SELECT 'GBC' FROM dual
)
SELECT c1, regexp_substr(c1, 'BC', 1, d.l, 'i') thePattern, d.l occurrence
  FROM t1 CROSS JOIN (SELECT LEVEL l FROM dual CONNECT BY LEVEL < 200) d
WHERE regexp_like(c1,'BC','i')
   AND d.l <= regexp_count(c1,'BC');

C1    THEPATTERN           OCCURRENCE
----- -------------------- ----------
ABCD  BC                            1
BCFBC BC                            1
BCFBC BC                            2
GBC   BC                            1

SQL>

Я произвольно ограничил число вхождений для поиска на 200, YMMV.

0 голосов
/ 22 июня 2011

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

create or replace package yo_package is
  type word_t  is record (word varchar2(4000));
  type words_t is table of word_t;
end;
/

create or replace package body yo_package is

  function table_function(in_cur in sys_refcursor, pattern in varchar2) 
  return words_t
    pipelined parallel_enable (partition in_cur by any)
  is
    next varchar2(4000);
    match varchar2(4000);
    word_rec word_t;
  begin
    word_rec.word = null;

    loop

    fetch in_cur into next;
    exit when in_cur%notfound;

    --this you inner loop where you loop through the matches within next
    --you have to implement this 
    loop
        --TODO get the next match from next     
        word_rec.word := match;
        pipe row (word_rec);    
    end loop;

    end loop;

  end table_function;

end;
/


select  *
from table(
    yo_package.table_function(
        cursor(
            --this is your first select
            select column1 from table1 where regexp_like(column1, pattern)
        )
    ) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...