Oracle 自定义wmsys.wm_concat 避免长度限制 网上搜索到这段类似代码但是长度过程还是不行,经过我的修改,亲测可以。
CREATE OR REPLACE TYPE ZH_CONCAT_IM
AUTHID CURRENT_USER AS OBJECT
(
CURR_STR CLOB,
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT ZH_CONCAT_IM) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT ZH_CONCAT_IM,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN ZH_CONCAT_IM,
RETURNVALUE OUT CLOB,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT ZH_CONCAT_IM,
SCTX2 IN ZH_CONCAT_IM) RETURN NUMBER
)
GOCREATE OR REPLACE TYPE BODY ZH_CONCAT_IM
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT ZH_CONCAT_IM)
RETURN NUMBER
IS
BEGIN
SCTX := ZH_CONCAT_IM(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT ZH_CONCAT_IM,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ',' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN ZH_CONCAT_IM,
RETURNVALUE OUT CLOB,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT ZH_CONCAT_IM,
SCTX2 IN ZH_CONCAT_IM)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
GO
CREATE OR REPLACE FUNCTION ZH_CONCAT(P1 VARCHAR2)
RETURN CLOB AGGREGATE USING ZH_CONCAT_IM ;
CREATE OR REPLACE TYPE ZH_CONCAT_IM
AUTHID CURRENT_USER AS OBJECT
(
CURR_STR CLOB,
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT ZH_CONCAT_IM) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT ZH_CONCAT_IM,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN ZH_CONCAT_IM,
RETURNVALUE OUT CLOB,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT ZH_CONCAT_IM,
SCTX2 IN ZH_CONCAT_IM) RETURN NUMBER
)
GOCREATE OR REPLACE TYPE BODY ZH_CONCAT_IM
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT ZH_CONCAT_IM)
RETURN NUMBER
IS
BEGIN
SCTX := ZH_CONCAT_IM(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT ZH_CONCAT_IM,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ',' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN ZH_CONCAT_IM,
RETURNVALUE OUT CLOB,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT ZH_CONCAT_IM,
SCTX2 IN ZH_CONCAT_IM)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
GO
CREATE OR REPLACE FUNCTION ZH_CONCAT(P1 VARCHAR2)
RETURN CLOB AGGREGATE USING ZH_CONCAT_IM ;
解决方案 »
- Oracle 中文排序问题
- 2018到2030年哪一年是闰年?语句怎么写?
- 请问怎么提升 oracle 大量数据删除插入的并行操作性能.
- oracle 删除导入的数据
- 关于验证数据合法性
- oracle8.1.7灾难恢复
- Oracle安装过程中出现问题
- 请帮忙写个触发器:每分钟、从视图中提取一记录写入表,谢谢!分不够了,谢谢
- pl\sql 查询问题
- Oracle日期高手請進!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- centos静默安装oracle11g报错,求帮助
- Oracle 11g自带的SQL Developer的SQL编辑器和执行结果中文显示乱码,求大神帮忙
select rtrim(xmlagg(xmlparse(content l||',' wellformed)) .getclobval() ,',') /* .getstringval()*/ from
(select level as l from dual connect by level<=5000)
自己以前总结过这几种用法,欢迎大家指正。
假如这种写法的名字是clob_concat,原写法返回varchar2的名字是vc_concat。
listagg限制太多,只有在11g才有且只能返回varchar2类型。vc_concat和clob_concat这两个内部函数不能内部排序,且内部聚合是混乱的。比如
select wm_concat(col1) col3,wm_concat(col2) col4 from tab;
返回的col3和col4里的聚合数据未必是一一对应的,这点不注意很容易出错。
关于效率对比:
分情况:
1、需要返回varchar2,不需排序的效率对比:【vc_concat】>【listagg】>【xmlagg】
2、需要返回clob,不需要排序的效率对比:【clob_concat】>【xmlagg】
3、需要返回varchar2,且需要排序的效率对比:【listagg】>【xmlagg】>【vc_concat网上流传的利用分析函数排序后取最大值的方法】
4、需要返回clob,且需要排序的效率对比:【xmlagg】>【clob_concat网上流传的利用分析函数排序后取最大值的方法】
总结:
不涉及排序或者对应的话优先选择vc_concat或者clob_concat,有排序的情况优先选择listagg,再考虑用2楼xmlagg的方法。