背景:由於技術架構的調整,數據庫需要進行遷移,將表和存儲過程從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。