Oracle 內建聚合函數(MAX、SUM、AVG 等)僅支援純量資料,對於物件型別、CLOB 等複雜類型無法直接使用。幸運的是,透過實作 ODCIAggregate 介面,開發者可建立自訂聚合函數,使用方式與內建函數無異。
CREATE OR REPLACE TYPE typ_concatenate_impl AS OBJECT ( retstr VARCHAR2(30000), separator VARCHAR2(64) DEFAULT ',', STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT typ_concatenate_impl) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateIterate(self IN OUT typ_concatenate_impl, value IN VARCHAR2) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateTerminate(self IN typ_concatenate_impl, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER, MEMBER FUNCTION ODCIAggregateMerge(self IN OUT typ_concatenate_impl, ctx2 IN typ_concatenate_impl) RETURN NUMBER );
CREATE OR REPLACE TYPE BODY typ_concatenate_impl IS
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT typ_concatenate_impl) RETURN NUMBER IS
BEGIN
sctx := typ_concatenate_impl('', ',');
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT typ_concatenate_impl, value IN VARCHAR2) RETURN NUMBER IS
BEGIN
self.retstr := self.retstr || value || self.separator;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateTerminate(self IN typ_concatenate_impl, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER IS
BEGIN
returnValue := SUBSTR(self.retstr, 1, LENGTH(self.retstr) - 1);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT typ_concatenate_impl, ctx2 IN typ_concatenate_impl) RETURN NUMBER IS
BEGIN
RETURN ODCICONST.SUCCESS;
END;
END;
CREATE OR REPLACE FUNCTION f_concatenate_str(i_str VARCHAR2) RETURN VARCHAR2 AGGREGATE USING typ_concatenate_impl;
CREATE TABLE test (id NUMBER, name VARCHAR2(20)); INSERT INTO test VALUES (1, 'AAA'); INSERT INTO test VALUES (2, 'BBB'); INSERT INTO test VALUES (1, 'ABC'); INSERT INTO test VALUES (3, 'CCC'); INSERT INTO test VALUES (2, 'DDD'); COMMIT;
| ID | f_concatenate_str(name) | wmsys.wm_concat(name) |
|---|---|---|
| 1 | AAA,ABC, | AAA,ABC |
| 2 | BBB,DDD, | BBB,DDD |
| 3 | CCC, | CCC |
兩者結果一致,差異僅在自訂函數保留結尾分隔符。Oracle 10g 內建未文件化的 wmsys.wm_concat 同樣可用,但自訂函數可彈性控制分隔符、排序等邏輯。
掌握 ODCIAggregate 介面,即可突破內建函數限制,打造領域專屬的聚合邏輯。