自定義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函數的過程,日誌記錄錯誤爲

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,不便於移植啊!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章