-------------------------------------------
-- 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函數的過程,日誌記錄錯誤爲
1
|
ORA-00932: inconsistent datatypes: expected - got CLOB
|
但是該過程在生產環境上運行正常不報錯。網上google之,該函數爲undocumented的,不被oracle官方支持,隨着版本變化也會有修改,但並不保證行爲一致。
測試環境爲
1
|
Oracle 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
生產環境爲
1
|
Oracle 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,不便於移植啊!