WM_CONCAT字符超过4000的处理办法 (ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小)

本文介绍了当在Oracle中使用WM_CONCAT或自定义聚合函数进行字符串拼接时,如果结果超过4000字符限制的解决方法。提供了两种有效方案:一是创建并使用特定函数将结果集转换为CLOB格式;二是利用Oracle SQL内置的XMLAGG函数来实现大字符串的拼接。
部署运行你感兴趣的模型镜像

在进行使用WM_CONCAT或者自定义的聚合函数,进行拼串的时候,可能遇到拼串形成的结果集大于4000,这时候,系统会提示,超过系统限制。所以,在这个时候,最好的处理办法就是将结果集处理成CLOB格式,

下面共有两种处理方式:

1、使用函数

类型:

 create or replace type str2tblType as table of varchar2(4000)

函数:

 CREATE OR REPLACE FUNCTION tab2clob(p_str2tbltype str2tbltype,
                     p_delim       IN VARCHAR2 DEFAULT ',') RETURN CLOB IS 
    l_result CLOB;
    BEGIN 
    FOR cc IN (SELECT column_value
                   FROM TABLE(p_str2tbltype)
                 ORDER BY column_value) LOOP
       l_result := l_result || p_delim || cc.column_value;
     END LOOP;
    RETURN ltrim(l_result, p_delim);
   END;

测试:

初始化数据:

 BEGIN2   FOR idx IN 1 .. 10000 LOOP
     INSERT INTO ts1 (tm) VALUES (sys_guid());
  END LOOP;
 END;

测试的SQL语句:

 SELECT tab2clob(CAST(COLLECT(tm) AS str2tbltype)) attributes
   FROM ts1
  WHERE rownum < 1000

注意:

如下的SQL语句错误:由于类型不同

1 SELECT sys_util.tab2clob(CAST(COLLECT(deptno) AS str2tbltype))
2   FROM (SELECT DISTINCT deptno FROM emp)

会抛出如下的异常信息:

因为在str2tbltype中声明的是varchar2,但是现在deptno是数字,所以数据类型会发生不一致,所以,可以使用to_char见其进行转换,来避免上述的错误:

1 SELECT sys_util.tab2clob(CAST(COLLECT(to_char(deptno)) AS str2tbltype))
2   FROM (SELECT DISTINCT deptno FROM emp)


二:使用Oracle的SQL提供的处理XML的语句:XMLAGG()

SQL语句如下:

1 SELECT rtrim(xmlagg(xmlparse(content ename || ',' wellformed) ORDER BY ename)
2              .getclobval(),
3              ',') attributes,
4        deptno
5   FROM emp
6  GROUP BY deptno;

结果:

具体:

   或者使用如下的语句,可以实现同样的功能:

 参考网站:http://www.williamrobertson.net/documents/one-row.html

1  SELECT deptno,
2        trim(xmlagg(xmlelement(content, ename || ',' ) ORDER BY ename)
3              .extract('//text()').getclobval())
4               AS concatenated
5   FROM emp
6  GROUP BY deptno;

下面的语句,没有调用getClobVal(),聚合的结果集是字符串

1  SELECT deptno,
2        trim(xmlagg(xmlelement(content, ename || ',' ) ORDER BY ename)
3              .extract('//text()'))
4               AS concatenated
5   FROM emp
6  GROUP BY deptno;

关于Oracle中XML的知识,请参考:http://www.oratechinfo.co.uk/sqlxml.html

或者http://www.cnblogs.com/caroline/archive/2012/11/15/2770887.html

转载自:http://www.cnblogs.com/caroline/archive/2012/11/13/2768902.html

参考网址:

http://stackoverflow.com/questions/11541383/ordering-by-list-of-strings-in-oracle-sql-without-listagg

字符串拼接技巧和方式:http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php

http://www.williamrobertson.net/documents/one-row.html


您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在处理一个关于Oracle数据库错误的问题:ORA-00904: "WM_CONCAT": invalid identifier。根据提供的引用信息,我们可以总结出以下内容: 1. 错误原因:在Oracle 12c及更高版本(如19c)中,`WM_CONCAT`函数已被废弃,因此当从低版本(如10g11g)迁移到高版本时,使用该函数的存储过程、视图等会报此错误2. 解决方案: - 方法1:在19c中创建低版本的`WM_CONCAT`函数(通过从11g复制并执行三个plb脚本文件)。 - 方法2:使用替代函数,如`LISTAGG`(这是Oracle官方推荐的字符串聚合函数)。 - 方法3:手动创建`WM_CONCAT`函数(通过执行特定的脚本)。 另外,引用[4]给出了使用`LISTAGG`替代`WM_CONCAT`的示例。 因此,我们的回答应该包括错误原因和多种解决方案,并给出示例。 注意:用户的问题是关于PL/SQL中遇到该错误,所以我们需要提供在PL/SQL中如何修改的指导。 根据要求,我们需要用中文回答,并生成相关问题。 回答结构: 1. 解释错误原因。 2. 提供解决方案,并给出具体步骤和示例。 3. 生成相关问题。 注意:引用标识要自然地添加在引用内容的末尾。</think>### PL/SQL ORA-00904: "WM_CONCAT" invalid identifier 解决方案 #### 错误原因 在 Oracle 12c 及以上版本(包括 19c)中,`WM_CONCAT` 函数已被官方弃用[^2]。当从低版本(如 10g/11g)迁移到高版本时,使用该函数的存储过程、视图 SQL 语句会触发 ORA-00904 错误,因为新版本数据库不再识别此函数[^1][^3]。 #### 解决方案 ##### 方法 1:使用 LISTAGG 替代(推荐) `LISTAGG` 是 Oracle 官方推荐的字符串聚合函数,语法更规范: ```sql SELECT dept_id, LISTAGG(employee_name, ',') WITHIN GROUP (ORDER BY employee_name) AS employees FROM employee_table GROUP BY dept_id; ``` 输出示例: ``` DEPT_ID | EMPLOYEES --------|---------- 10 | 张三,李四,王五 ``` ##### 方法 2:重建 WM_CONCAT 函数 在 19c 中手动创建兼容函数(需 DBA 权限): 1. 从 Oracle 11g 复制以下文件到 19c 的 `$ORACLE_HOME/rdbms/admin/`: - `owmctab.plb` - `owmaggrs.plb` - `owmaggrb.plb` 2. 按顺序执行脚本: ```sql @?/rdbms/admin/owmctab.plb @?/rdbms/admin/owmaggrs.plb @?/rdbms/admin/owmaggrb.plb ``` 执行后需重新编译依赖对象[^3]。 ##### 方法 3:使用自定义聚合函数 创建自定义聚合函数(兼容性更好): ```sql CREATE TYPE string_agg_type AS OBJECT ( str_list VARCHAR2(4000), STATIC FUNCTION ODCIAggregateInitialize(...) ..., MEMBER FUNCTION ODCIAggregateIterate(...) ..., MEMBER FUNCTION ODCIAggregateTerminate(...) ... ); ``` #### 迁移建议 1. **开发环境**:优先使用 `LISTAGG` 重写逻辑 2. **生产环境**: - 紧急修复:临时重建 `WM_CONCAT` - 长期方案:逐步替换为 `LISTAGG` `JSON_ARRAYAGG` 3. 注意 `LISTAGG` 的 4000 字节限制,超限时需使用 `CLOB` 分组合并[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值