LISTAGG 函数:短字符串 return ORA-01489:字符串连接的结果太长

LISTAGG function: Short string return ORA-01489: result of string concatenation is too long

我有一个查询要从使用多个电子邮件地址维护的列中提取电子邮件域。列值为aaa@yahoo.com、bbb@hotmail.com,列大小为VARCHAR2(3500 CHAR)

以下查询使用 listagg 函数提取域并以正则表达式为前缀:

SELECT DISTINCT
LISTAGG( CHR(91)||'a-zA-Z0-9._%-'||CHR(93)||'+' ||REGEXP_SUBSTR(EMAIL_STRING,'@' || CHR(91) || '^,' 
|| CHR(93) ||'+', 1, LEVEL), ',')
WITHIN GROUP (ORDER BY LEVEL) AS  USER_EMAILS_DOMAIN
FROM EMAIL_PARAMETER WHERE NAME='UserEmails'
CONNECT BY REGEXP_SUBSTR(EMAIL_STRING,'@'||CHR(91)||'^,'||CHR(93)||'+', 1, LEVEL) IS NOT NULL;

预期结果:[a-zA-Z0-9.%-]+@yahoo.com,[a-zA-Z0-9.%-] +@hotmail.com

字符串在4000个字符以内,然而Oracle return ORA-01489: result of string concatenation is too long

我尝试使用 LISTAGG with ON OVERFLOW TRUNCATE 选项,它 return 是第二封电子邮件的长字符串,bbb@hotmail.com 不断重复。

我也尝试 XMLTAGG,我也收到了一个很长的字符串,两封电子邮件都在重复。

select rtrim(xmlagg(xmlelement(e,CHR(91)||'a-zA-Z0-9._%-'||CHR(93)||'+' || EMAIL_STRING,',').extract('//text()') order by REGEXP_SUBSTR(EMAIL_STRING,'@' || CHR(91) || '^,' || CHR(93) ||'+', 1, LEVEL)).getclobval(),',') USER_EMAILS_DOMAIN
FROM EMAIL_PARAMETER WHERE NAME='UserEmails' 
CONNECT BY REGEXP_SUBSTR(EMAIL_STRING,'@'||CHR(91)||'^,'||CHR(93)||'+', 1, LEVEL) IS NOT NULL;

看起来 DISTINCT 并没有如您所愿。

首先 select所有不同的域,然后对结果应用listagg

简化版:

select listagg(domain, ',') within group (order by domain) final_result  --> 2. aggregation
from 
     (select distinct regexp_substr(email_string, ...) as domain         --> 1. distinct domains
      from email_parameter
     )