自定义聚集函数代替wm_concat,WM_CONCAT字符超过4000的处理办法

-- 准备数据
create table test(id number,name varchar2(100));

-- 删除表,测试后不需要时调用
drop table test  

-- 测试数据
insert into test values(1,'a');  
insert into test values(1,'b');  
insert into test values(1,'c');  
insert into test values(2,'d');  
insert into test values(2,'e');  

-- 检查测试数据
select * from test

--测试系统自带wm_concat
select wm_concat(name) from test


-------------------------------------------------------------------------------------开始
-- 步骤1:自定义一个类型【str2tblType 】
create or replace type str2tblType as table of varchar2(4000)


-- 步骤2:自定义函数【my_wm_concat】
CREATE OR REPLACE FUNCTION my_wm_concat(
    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;

-- 步骤3-初始化测试数据
BEGIN   
  FOR idx IN 1 .. 10000 LOOP
  INSERT INTO test(id,name) VALUES (1,sys_guid());
  END LOOP;
END;

-- 步骤4-调用测试1
SELECT my_wm_concat(CAST(COLLECT(name) AS str2tbltype)) attributes
FROM test
WHERE rownum < 1000;

SELECT my_wm_concat(
  CAST(COLLECT(emp_name) AS str2tbltype))
FROM  dim_employee

SELECT my_wm_concat(
  CAST(COLLECT(emp_name) AS str2tbltype),
  'aa'-- 分割字符,若不传,默认','
  )
FROM  dim_employee

是的,Oracle的`concat`函数只能处理4000字符以下的字符串连接。如果需要处理更长的字符串,可以使用自定义聚合函数来实现。以下是一个示例函数,模仿Oracle的`wm_concat`函数: ```sql CREATE OR REPLACE TYPE t_varchar2_list AS TABLE OF VARCHAR2(4000); CREATE OR REPLACE FUNCTION wm_concat_clob (p_list t_varchar2_list) RETURN CLOB AGGREGATE USING wm_concat_clob_agg; CREATE OR REPLACE TYPE wm_concat_clob_agg AS OBJECT ( g_list CLOB, STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT wm_concat_clob_agg) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateIterate ( SELF IN OUT wm_concat_clob_agg, VALUE IN VARCHAR2 ) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateTerminate ( SELF IN wm_concat_clob_agg, RETURN_VALUE OUT CLOB, flags IN NUMBER ) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateMerge ( SELF IN OUT wm_concat_clob_agg, ctx2 IN wm_concat_clob_agg ) RETURN NUMBER ); CREATE OR REPLACE TYPE BODY wm_concat_clob_agg IS STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT wm_concat_clob_agg) RETURN NUMBER IS BEGIN sctx := wm_concat_clob_agg (NULL); RETURN ODCIConst.SUCCESS; END; MEMBER FUNCTION ODCIAggregateIterate ( SELF IN OUT wm_concat_clob_agg, VALUE IN VARCHAR2 ) RETURN NUMBER IS BEGIN SELF.g_list := SELF.g_list || VALUE || ','; RETURN ODCIConst.SUCCESS; END; MEMBER FUNCTION ODCIAggregateTerminate ( SELF IN wm_concat_clob_agg, RETURN_VALUE OUT CLOB, flags IN NUMBER ) RETURN NUMBER IS BEGIN RETURN_VALUE := rtrim (SELF.g_list, ','); RETURN ODCIConst.SUCCESS; END; MEMBER FUNCTION ODCIAggregateMerge ( SELF IN OUT wm_concat_clob_agg, ctx2 IN wm_concat_clob_agg ) RETURN NUMBER IS BEGIN SELF.g_list := SELF.g_list || ctx2.g_list; RETURN ODCIConst.SUCCESS; END; END; ``` 使用示例: ```sql SELECT wm_concat_clob (CAST (COLLECT (column_name) AS t_varchar2_list)) FROM user_tab_columns WHERE table_name = 'EMPLOYEES'; ``` 这将返回一个包含所有列名的CLOB字符串,无论它们的长度是多少。注意,由于使用CLOB,这可能会影响性能,因此请谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值