从NVARCHAR2 DATATYPE获取电子邮件地址

时间:2016-11-24 06:13:24

标签: sql database oracle plsql oracle11g

我有一个表,其中有一列NVARCHAR2数据类型,其中包含一个字符串。 该字符串包含一些我需要以逗号分隔方式获取的电子邮件ID。

以下是测试数据 -

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 <manoj.dalai@gmail.com>: Recipient address rejected: User unknown in virtual alias table;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <santoshi.k@gmail.com>: Recipient address rejected: User unknown in virtual alias table
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <biswajit-kumar.p@gmail.com>: 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 <manoj.dalai@gmail.com>: Recipient address rejected: User unknown in virtual alias table;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <santoshi.k@gmail.com>: Recipient address rejected: User unknown in virtual alias table');

我正在尝试使用以下SQL,但它正在重复电子邮件ID !!

select email_rejetc, listagg(REGEXP_substr (email_rejetc,'[A-Za-z0-9._%+-]+@[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._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}') 
group by EMAIL_REJETC

此处所需的输出类似于

manoj.dalai@gmail.com,santosh.k@gmail.com,biswajit-kumar@gmail.com

表格的不同行中的电子邮件数量可以是VARY;

我的数据库是: Oracle Database 11g企业版11.2.0.3.0版 - 64位生产

2 个答案:

答案 0 :(得分:2)

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

from     nvarchar2_email e
;

P.S。

regexp_substr和nvarchar似乎存在问题,导致结果中的每个字符都以\ 0开头。
在Oracle Database 11g Express Edition 11.2.0.2.0版上进行测试 - 64位生产

答案 1 :(得分:0)

根据您的示例,电子邮件地址似乎始终显示为<aaaa@bbbb>,表示<,中间带有@的字符串,以及>签名。

您可以尝试这样的事情(无法检查语法,因此您可能需要进行一些测试):

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

这将在字符串中产生 FIRST 电子邮件地址。您可以在循环中使用相同的概念(提供不包含第一个电子邮件地址的第一部分的字符串)来提取同一字符串中的其他地址。

我无法通过一个单一的&#34; SELECT&#34;声明,因为每个字符串可能有几个(而不是所有字符串的数量相同)地址。

调查的一个选项是实现递归选择(Oracle支持此选项),但它会复杂得多。

就个人而言,我会采用上面提出的方法。