ORA-00904: "WM_CONCAT": invalid identifier 解决方案
背景:由于技术架构的调整,数据库需要进行迁移,将表和存储过程从Oracle数据库迁移到另外一个Oracle数据库,在存储过程迁移过程中,遇到个问题,使用WM_CONCAT的存储过程编译不会通过,并且报 ORA-00904: "WM_CONCAT": invalid identifier 错误。
产生原因:在查一些资料后,发现11gr2之后的版本中WM_CONCAT函数已经弃用,而应用在程序中确使用了该函数,导致程序出现错误。
解决方案:
1、如果你是11gR2之后的版本,建议使用LISTAGG代替WM_CONCAT
with mock_data as( select 'Mike' NAME , 1 aa from dual union all select 'Amber' NAME,2 from dual union all select 'James' NAME,3 from dual union all select 'Albert' NAME,4 from dual ) SELECT LISTAGG(NAME, ', ') WITHIN GROUP (ORDER BY name) name_list FROM mock_data ; NAME_LIST -------------------------- Mike, Amber, James, Albert
2、自己创建WM_CONCAT函数
CREATE OR REPLACE TYPE wm_concat_impl 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 ); / 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; /
复制粘贴执行即可。
若之前使用WM_CONCAT较多,建议使用方法2创建函数,但之后需要进行聚合的时候建议使用LISTAGG。