我想使用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'的表格。
答案 0 :(得分:1)
您也可以在一个查询中执行此操作,不需要函数/过程/包:
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搜索的出现次数。
答案 1 :(得分:0)
实际上,在一个查询中有一种优雅的方法可以执行此操作,如果您不介意运行一些额外的里程。请注意,这只是一个草图,我没有运行它,你可能需要更正其中的一些拼写错误。
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)
)
)