关于:新版本Oracle 试用 listagg 替代 wm_concat导致的问题

本文介绍在Oracle 12C环境下,如何解决因wm_concat函数缺失导致的异常问题。通过解锁wmsys用户,创建自定义wm_concat函数及同义词,并进行授权,使原有依赖此函数的代码能在新环境中正常运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们做过很多项目,随着发展,数据库的版本也会随着更新,一个新项目从头开始那很少会有遇到版本的问题,不过在一些老项目,需要升级数据库,或者不熟新的测试环境等等更换了数据库版本,可能就会出现原系统中的写好的sql开始抛异常。

这不,昨天要搭建一个临时的试运行环境,可是提供的数据库版本变成了12c 时间比较紧,就直接创建实例开始导库,一切都不是好了,测试服务工能的时候开始抛异常了

"wmsys"."wm_concat" 找不到了。

这时如果要修改代码首先工作量很大,其次与生产版本也冲突了。

看到很多人分享解决方法那就是,在12C中复写实现wmsys.wm_concat ,基本实现如下:

一.解锁wmsys用户

alter user wmsys account unlock;

二.创建包、包体和函数

以wmsys用户登录数据库,执行下面的命令

CREATE OR REPLACE TYPE WM_CONCAT_IMPL AS OBJECT
-- AUTHID CURRENT_USER AS OBJECT
(
    CURR_STR VARCHAR2(32767), 
    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL) RETURN NUMBER,
    MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
        P1 IN VARCHAR2) RETURN NUMBER,
    MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
        RETURNVALUE OUT VARCHAR2,
        FLAGS IN NUMBER)
        RETURN NUMBER,
    MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
        SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
);
/
 
--定义类型body:
CREATE OR REPLACE TYPE BODY WM_CONCAT_IMPL
IS
    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
    RETURN NUMBER
    IS
    BEGIN
        SCTX := WM_CONCAT_IMPL(NULL) ;
        RETURN ODCICONST.SUCCESS;
    END;

    MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
        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 WM_CONCAT_IMPL,
        RETURNVALUE OUT VARCHAR2,
        FLAGS IN NUMBER)
    RETURN NUMBER
    IS
    BEGIN
        RETURNVALUE := CURR_STR ;
        RETURN ODCICONST.SUCCESS;
    END;

    MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
        SCTX2 IN WM_CONCAT_IMPL)
    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;
/

--自定义行变列函数:
CREATE OR REPLACE FUNCTION wm_concat(P1 VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING WM_CONCAT_IMPL ;
/

三.创建同义词并授权

create public synonym WM_CONCAT_IMPL for wmsys.WM_CONCAT_IMPL
/
create public synonym wm_concat for wmsys.wm_concat
/
 
grant execute on WM_CONCAT_IMPL to public
/
grant execute on wm_concat to public
/