自定义oracle聚集函数,类似于功能wm_concat

-------------------------------------------
-- Export file for user BOSS1214         --
-- Created by user on 2011-2-25, 9:34:30 --
-------------------------------------------

spool str_sum_sql.log

prompt
prompt Creating type STR_SUM_OBJ
prompt =========================
prompt
CREATE OR REPLACE TYPE STR_SUM_OBJ AS OBJECT --聚合函数的实质就是一个对象
(
  SUM_STRING VARCHAR2(4000),
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(V_SELF IN OUT STR_SUM_OBJ)
    RETURN NUMBER, --对象初始化

--聚合函数的迭代方法(这是最重要的方法)
  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF  IN OUT STR_SUM_OBJ,
                                       VALUE IN VARCHAR2) RETURN NUMBER,

--当查询语句并行运行时,才会使用该方法,可将多个并行运行的查询结果聚合
  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF   IN OUT STR_SUM_OBJ,
                                     V_NEXT IN STR_SUM_OBJ)
    RETURN NUMBER,

--终止聚集函数的处理,返回聚集函数处理的结果.
  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF         IN STR_SUM_OBJ,
                                         RETURN_VALUE OUT VARCHAR2,
                                         V_FLAGS      IN NUMBER)
    RETURN NUMBER

)
/

prompt
prompt Creating function STR_SUM
prompt =========================
prompt
CREATE OR REPLACE FUNCTION STR_SUM(VALUE VARCHAR2) RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING STR_SUM_OBJ;
/

prompt
prompt Creating type body STR_SUM_OBJ
prompt ==============================
prompt
CREATE OR REPLACE TYPE BODY STR_SUM_OBJ IS
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(V_SELF IN OUT STR_SUM_OBJ)
    RETURN NUMBER IS
  BEGIN
    V_SELF := STR_SUM_OBJ(NULL);
    RETURN ODCICONST.SUCCESS;
  END;

  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF  IN OUT STR_SUM_OBJ,
                                       VALUE IN VARCHAR2) RETURN NUMBER IS
  BEGIN
    SELF.SUM_STRING := SELF.SUM_STRING || VALUE;
    RETURN ODCICONST.SUCCESS;
  END ODCIAGGREGATEITERATE;

  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF   IN OUT STR_SUM_OBJ,
                                     V_NEXT IN STR_SUM_OBJ)
    RETURN NUMBER IS
  BEGIN
    SELF.SUM_STRING := SELF.SUM_STRING || V_NEXT.SUM_STRING;
    RETURN ODCICONST.SUCCESS;
  END ODCIAGGREGATEMERGE;

  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF         IN STR_SUM_OBJ,
                                         RETURN_VALUE OUT VARCHAR2,
                                         V_FLAGS      IN NUMBER)
    RETURN NUMBER IS
  BEGIN
    RETURN_VALUE := SELF.SUM_STRING;
    RETURN ODCICONST.SUCCESS;
  END ODCIAGGREGATETERMINATE;
END;
/


spool off

 

 

示例用法如下:

select STR_SUM(pi.productcode || ',')
  from t_productinfos pi
 where pi.producttypecode = '00';

 另外,wm_concat函数,在一些oracle版本里可能会返回clob类型,导致程序出错。

因此wm_concat是WMSYS下的东西oracle内部用的,一般程序中最好不要用到它。

 

 

*********************************************************************************

今天在测试环境上运行一个使用到wmsys.wm_concat函数的过程,日志记录错误为

1ORA-00932: inconsistent datatypes: expected - got CLOB

但是该过程在生产环境上运行正常不报错。网上google之,该函数为undocumented的,不被oracle官方支持,随着版本变化也会有修改,但并不保证行为一致。

测试环境为

1Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 compatible string 10.2.0.3.0

重启并修改compatible string 为10.2.0.5.0,测试wmsys.wm_concat返回值仍为CLOB

生产环境为

1Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 compatible string 11.2.0.0.0

最终解决方法是在wm_concat外层用to_char作转换。 PS:之前在11g生产环境中用过一次wm_concat,结果发现在同一个select子句中使用该函数不能超过两次,于是换用listagg和正则表达式解决了问题。看来以后尽量避免使用wmsys.wm_concat,不便于移植啊!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值