2016-11-24 11 views
0

文字列を保持するNVARCHAR2データ型の列があるテーブルがあります。 文字列には、カンマ区切りでフェッチする必要のある電子メールIDが含まれています。NVARCHAR2から電子メールアドレスを取得するDATATYPE

は、以下の試験データである -

create table nvarchar2_email (email_reject nvarchar2(1000)); 

insert into nvarchar2_email values ('com.wm.app.b2b.server.ServiceException:  javax.mail.SendFailedException: Invalid Addresses; nested exception is: 
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual alias table; 
nested exception is: 
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual alias table 
nested exception is: 
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual alias table'); 

insert into nvarchar2_email values ('com.wm.app.b2b.server.ServiceException: javax.mail.SendFailedException: Invalid Addresses; nested exception is: 
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual alias table; 
nested exception is: 
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual alias table'); 

私は、以下のSQLを使用しようとしていますが、それは電子メールのIdsを繰り返しています!

select email_rejetc, listagg(REGEXP_substr (email_rejetc,'[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,4}', 1,level), ',') within group (order by email_rejetc) invalid_email 
from nvarchar2_email 
connect by level <= REGEXP_count (email_rejetc,'[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,4}') 
group by EMAIL_REJETC 

ここで必要な出力がメールの数は、テーブルの異なる行に変えることができ

[email protected],[email protected],[email protected] 

のようなものです。

私のDBは次のとおりです。 Oracle Database 11gのEnterprise Editionのリリース11.2.0.3.0 - 64ビットの生産

答えて

2
select (select   listagg (regexp_substr(cast(e.email_reject as varchar2(1000)),'<(.*[email protected]*?)>',1,level,'',1),',') 
          within group (order by e.email_reject) 
     from   dual 
     connect by  level <= regexp_count (e.email_reject,'<.*[email protected]*?>') 
     )  as emails       

from  nvarchar2_email e 
; 

p.s.

regexp_substrとnvarcharには、結果の各文字の前に\ 0を付けるという問題があるようです。
は、Oracle Database 11グラムExpress Editionのリリース11.2.0.2.0でテスト - 64ビットの生産

+0

すごくうまくいっている – mradul

0

あなたの例によると、<を意味し、電子メールアドレスは必ず<[email protected]>として提示されたように思われます、中央に@の文字列、>という符号が付いています。

あなたはこのような何かを試みることができる(構文をチェックすることはできませんが、あなたはいくつかのテストを行うために必要がある場合があります):

SUBSTR(<input string>            , 
     INSTR(<input string>,'<') + 1        , 
     (INSTR(<input string>,'>') - INSTR(<input string>,'<') - 2 
     ) ; 

これは文字列内FIRST電子メールアドレスを生成します。同一の文字列内の追加アドレスを抽出するために同じコンセプト(最初の電子メールアドレスを含む最初のセクションがない文字列を提供する)をループ内で使用できます。

各文字列にいくつかの(そしてすべての文字列の数が同じではない)アドレスがある可能性があるため、単一の "SELECT"ステートメントでこれを行う方法はありません。

調査する1つのオプションは、再帰的な選択を実装することです(Oracleはこれをサポートしています)が、はるかに複雑になります。

個人的には、私は上記のアプローチに行きます。

+0

私は私の最初の試みで、INSTRのSUBSTRを使用してみましたが、それは常に私の最初の電子メールIDを与えるだけで、私はINSTRで<,>の位置を宣言した場合に対し、 2番目の電子メールアドレスに移動する関数私はSQLでこれを行う必要があるだけです。 – mradul

+0

確かに。最初のファイルを見つけたら、次の検索の開始( '<'のため)を**の後**に、電子メールアドレスの末尾に移動する必要があります。そのため、各文字列に対して単純なループを実装する必要があると述べました。 – FDavidov