You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LISTAGG报Ora-1489拼接字符串过长错误,尝试用XMLAGG解决

Oracle LISTAGG触发ORA-01489错误的解决方法

错误原因

ORA-01489报错是因为LISTAGG函数拼接后的字符串长度超出了VARCHAR2类型的上限(默认最大4000字节,开启32k扩展后最大32767字节),如果拼接结果确实会超出上限,使用支持返回CLOB类型的XMLAGG函数是最常用的规避方案。

现有代码问题

你已经注释了XMLAGG的写法,但存在两处错误:

  • 多余嵌套了一层XMLAGG,不需要双重封装
  • 没有处理拼接后末尾多余的逗号,也没有规避XML特殊字符转义的问题

修正后的代码

只需要把子查询中LISTAGG的部分替换为以下逻辑即可:

-- 注释原有LISTAGG逻辑
-- listagg((PEA.EMAIL_ADDRESS || ','|| LOBS.EMAIL1), ',') within group (order by LOCT.internal_location_code) LEARN_OBS_EMAIL
-- 替换为修正后的XMLAGG逻辑
RTRIM(
  XMLAGG(
    XMLELEMENT(E, PEA.EMAIL_ADDRESS || ',' || LOBS.EMAIL1 || ',')
    .EXTRACT('//text()') 
    ORDER BY LOCT.internal_location_code
  ).GETCLOBVAL(),
  ','
) AS LEARN_OBS_EMAIL

完整修正后的SQL如下:

SELECT DISTINCT 
  LEARN_OBS_LCODE                       "KEY", 
  'Results'                              "TEMPLATE", 
  'en-US'                                "LOCALE", 
  'html'                                 OUTPUT_FORMAT, 
  'TTX Checklist Activity Notification' "OUTPUT_NAME", 
  'EMAIL'                                DEL_CHANNEL, 
  LEARN_OBS_EMAIL                        "PARAMETER1",
  -- "PARAMETER2",
  'ejjc.fa.sender@workflow.mail.us6.oraclecloud.com' "PARAMETER3", 
  '(' || LEARN_OBS_LNAME || ') ' || 'Observation Checklist Pending' 
  || ' - ' 
  || TO_CHAR(sysdate, 'MM/DD/YYYY')      "PARAMETER4", 
  'true'                                 "PARAMETER6"
FROM  (
  SELECT DISTINCT 
    RTRIM(LOCT.internal_location_code) LEARN_OBS_LCODE,
    RTRIM(LOC.location_name) LEARN_OBS_LNAME,
    RTRIM(
      XMLAGG(
        XMLELEMENT(E, PEA.EMAIL_ADDRESS || ',' || LOBS.EMAIL1 || ',')
        .EXTRACT('//text()') 
        ORDER BY LOCT.internal_location_code
      ).GETCLOBVAL(),
      ','
    ) AS LEARN_OBS_EMAIL
  FROM fusion.per_all_people_f PAPF 
  INNER JOIN fusion.per_person_names_f PER 
    ON PAPF.person_id = PER.person_id 
    AND TRUNC(sysdate) BETWEEN PER.effective_start_date AND PER.effective_end_date 
    AND PER.name_type = 'GLOBAL'
  LEFT JOIN FUSION.PER_USERS PLU  
    ON PLU.PERSON_ID = PAPF.PERSON_ID  
    AND TRUNC(sysdate) BETWEEN PLU.START_DATE AND NVL(PLU.END_DATE,TRUNC(sysdate))
    AND PLU.ACTIVE_FLAG = 'Y'
    --AND PLU.USERNAME  = FND_GLOBAL.USER_NAME 
  LEFT JOIN FUSION.PER_USER_ROLES PUR     
    ON PUR.USER_ID = PLU.USER_ID 
    AND TRUNC(sysdate) BETWEEN PUR.START_DATE AND NVL(PUR.END_DATE, TRUNC(sysdate))
  LEFT JOIN FUSION.PER_ROLES_DN PR_BASE   
    ON PR_BASE.ROLE_ID = PUR.ROLE_ID
  LEFT JOIN FUSION.PER_ROLES_DN_TL PLR    
    ON PLR.ROLE_ID = PR_BASE.ROLE_ID 
    AND PLR.LANGUAGE = USERENV('LANG')  
    AND PLR.ROLE_NAME IS NOT NULL       
  INNER JOIN fusion.per_all_assignments_f ASG 
    ON ASG.person_id = PAPF.person_id 
    AND TRUNC(sysdate) BETWEEN ASG.effective_start_date AND ASG.effective_end_date 
    AND ASG.primary_flag = 'Y' 
    AND ASG.assignment_type IN ( 'E', 'C','N' ) 
    AND ASG.effective_latest_change = 'Y' 
    AND ASG.assignment_status_type <> 'INACTIVE' 
  LEFT JOIN per_location_details_f_vl LOC 
    ON ASG.location_id = LOC.location_id 
    AND TRUNC(sysdate) BETWEEN LOC.effective_start_date AND LOC.effective_end_date 
  LEFT JOIN per_locations LOCT 
    ON LOC.location_id = LOCT.location_id 
  LEFT JOIN fusion.per_email_addresses PEA 
    ON PEA.person_id = PAPF.person_id 
    AND TRUNC(sysdate) BETWEEN PEA.date_from AND NVL(PEA.date_to, TRUNC(sysdate)) 
    AND PEA.email_type = 'W1' 
  INNER JOIN LEARN_OBSERVER LOBS
    ON ASG.LOCATION_ID = LOBS.LOCATION_ID
  WHERE TRUNC(sysdate) BETWEEN PAPF.effective_start_date AND PAPF.effective_end_date
    --and papf.person_number = '38148'                                  
    AND UPPER(PR_BASE.ROLE_COMMON_NAME) = 'TTX_LEARNING_OBSERVER_BY_LOCATION_DATA'
    --AND UPPER(PLR.ROLE_NAME) = 'TTX LEARNING OBSERVER BY LOCATION'
  GROUP BY LOCT.internal_location_code , LOC.location_name 
)

注意事项

  • 修正后返回的LEARN_OBS_EMAIL为CLOB类型,若后续使用场景要求VARCHAR2类型,且确认拼接后长度不超过32767字节,可在外层嵌套TO_CHAR()转换
  • 如果你使用的是Oracle 12cR2及以上版本,也可以选择在LISTAGG后添加ON OVERFLOW TRUNCATE '...' WITH COUNT参数处理超长问题,该方案会截断超出长度的内容,适合可接受截断的场景

内容的提问来源于stack exchange,提问作者Suresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 00:06:03