2011-06-22 71 views
1

我想使用Oracle 11g中的正則表達式從列中提取文本。我有兩個查詢可以完成這項工作,但我正在尋找一種(更清潔/更好的)方式來完成這項工作。也許可以將查詢合併爲一個或一個新的等價查詢。它們是:如何從Oracle 11g中的表中提取模式?

查詢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

有趣的......你能發佈一個什麼樣的數據看起來像樣本和期望的結果嗎? – FrustratedWithFormsDesigner

+0

+1 - 有趣的練習! – DCookie

回答

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搜索,因人而異。

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) 
     ) 
    ) 
+1

http://static.images.memegenerator.net/Instances400/8/8201/8398245.jpg – bpgergo