CREATE FUNCTION ... AGGREGATE USING type_name
CREATE FUNCTION ... AGGREGATE USING type_name語法是用戶創(chuàng)建自定義的聚合函數(shù)。
簡介
PolarDB數(shù)據(jù)庫提供了幾種預(yù)定義的聚合函數(shù)。例如,MAX、MIN和SUM用于對一組行執(zhí)行操作。這些預(yù)定義的聚合函數(shù)只能用于標(biāo)量數(shù)據(jù),不能用于復(fù)雜的數(shù)據(jù)類型。例如使用對象類型、不透明類型和LOB存儲的多媒體數(shù)據(jù)。
CREATE FUNCTION ... AGGREGATE USING type_name可以用來為復(fù)合數(shù)據(jù)類型創(chuàng)建自定義的聚合函數(shù)。還可以定義全新的聚合函數(shù)來處理復(fù)雜數(shù)據(jù)。用戶定義的聚合函數(shù)可以在SQL DML語句中使用,如同內(nèi)置聚合函數(shù)一樣。
用戶定義的聚合函數(shù)是可擴(kuò)展性框架的一項功能,用戶可以使用ODCIAggregate接口函數(shù)來實現(xiàn)。
用戶可以通過實現(xiàn)一組統(tǒng)稱為ODCIAggregate的函數(shù)來創(chuàng)建一個用戶定義的聚合函數(shù)。可以將這些函數(shù)實現(xiàn)為對象類型中的方法。當(dāng)定義對象類型并在類型主體中實現(xiàn)函數(shù)時,使用該CREATE FUNCTION
語句創(chuàng)建聚合函數(shù)。
每個用戶定義的聚合函數(shù)最多使用四個ODCIAggregate函數(shù)或步驟來定義任何聚合函數(shù)執(zhí)行的內(nèi)部操作,包括初始化、迭代、合并和終止。
函數(shù)名稱 | 說明 |
ODCIAggregateInitialize | Oracle調(diào)用該函數(shù)來初始化用戶定義聚合的計算。初始化的聚合上下文作為對象類型實例傳遞回Oracle。 |
ODCIAggregateIterate | Oracle重復(fù)調(diào)用該函數(shù)。每次調(diào)用時,都會將一個新值(或一組新值)作為輸入傳遞。當(dāng)前聚合上下文也被傳入。函數(shù)處理新值并將更新的聚合上下文返回給Oracle。為基礎(chǔ)組中的每個非NULL值調(diào)用此函數(shù)。(NULL值在聚合期間被忽略,不會傳遞給函數(shù)。) |
ODCIAggregateMerge | Oracle調(diào)用該函數(shù)來組合兩個聚合上下文。該函數(shù)將兩個上下文作為輸入,組合它們,并返回單個聚合上下文。 |
ODCIAggregateTerminate | 該函數(shù)由Oracle作為聚合的最后一步調(diào)用。該函數(shù)將聚合上下文作為輸入并返回生成的聚合值。 |
語法
CREATE TYPE SpatialUnionRoutines(
STATIC FUNCTION ODCIAggregateInitialize( ... ) ...,
MEMBER FUNCTION ODCIAggregateIterate(...) ... ,
MEMBER FUNCTION ODCIAggregateMerge(...) ...,
MEMBER FUNCTION ODCIAggregateTerminate(...)
);
CREATE TYPE BODY SpatialUnionRoutines IS
...
END;
CREATE FUNCTION SpatialUnion(x int) RETURN int
AGGREGATE USING SpatialUnionRoutines;
參數(shù)說明
ODCIAggregateInitialize
STATIC FUNCTION ODCIAggregateInitialize(
actx IN OUT <impltype>)
RETURN NUMBER
參數(shù) | In/Out | 說明 |
actx | IN OUT | 由例程初始化的聚合上下文。該值適用NULL與常規(guī)聚合情況。在窗口聚合中,actx是前一個窗口的上下文。該對象實例作為參數(shù)傳遞給下一個聚合例程。 |
ODCIAggregateIterate
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT <impltype>,
val <inputdatatype>)
RETURN NUMBER
參數(shù) | In/Out | 描述 |
self | IN OUT |
|
val | IN | 正在聚合的輸入值。 |
ODCIAggregateMerge
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT <impltype>,
ctx2 IN <impltype>)
RETURN NUMBER
參數(shù) | In/Out | 說明 |
self | IN OUT |
|
ctx2 | IN | 第二個聚合上下文的值。 |
ODCIAggregateTerminate
MEMBER FUNCTION ODCIAggregateTerminate(
self IN <impltype>,
ReturnValue OUT <return_type>,
flags IN number)
RETURN NUMBER
參數(shù) | In/Out | 說明 |
self | IN | 聚合上下文的值。 |
ReturnValue | OUT | 所得聚合值。 |
flags | IN | 指示各種選項的位向量。一組位ODCI_AGGREGATE_REUSE_CTX指示上下文被重用,并且不應(yīng)釋放任何外部上下文。 |
原理介紹(并行聚合)
用戶定義聚合的并行評估
與內(nèi)置聚合函數(shù)一樣,用戶定義的聚合可以并行計算。但是,聚合函數(shù)必須聲明為啟用并行。
創(chuàng)建函數(shù)
MyUDAG(...)
返回... PARALLEL_ENABLE
聚合使用MyAggrRoutines。通過聚合并行從屬中的行子集生成的聚合上下文被發(fā)送回下一個并行步驟(查詢協(xié)調(diào)器或下一個從集)。
調(diào)用Merge例程來合并聚合上下文,最后調(diào)用Terminate例程獲取聚合值。
調(diào)用流程如下:
處理大型聚合上下文
當(dāng)使用外部語言(如C或Java)實現(xiàn)類型方法時,每次調(diào)用實現(xiàn)類型方法時,都必須在數(shù)據(jù)庫服務(wù)器進(jìn)程和外部函數(shù)的語言環(huán)境之間來回傳遞聚合上下文。
傳遞大型聚合上下文會對性能產(chǎn)生不利影響。為避免這種情況,您可以將聚合上下文存儲在外部內(nèi)存中,在外部函數(shù)的執(zhí)行環(huán)境中分配,并僅將引用或鍵傳遞給上下文而不是上下文本身。密鑰應(yīng)存儲在實現(xiàn)類型實例(self)中,然后可以在數(shù)據(jù)庫服務(wù)器和外部函數(shù)之間傳遞密鑰。
將鍵傳遞給上下文而不是上下文本身可以使實現(xiàn)類型實例保持較小,以便可以快速傳輸。此策略的另一個優(yōu)點是用于保存聚合上下文的內(nèi)存是在函數(shù)的執(zhí)行環(huán)境(例如,extproc)中分配的,而不是在數(shù)據(jù)庫服務(wù)器中。
通常應(yīng)該分配內(nèi)存來保存聚合上下文ODCIAggregateInitialize并將對它的引用存儲在實現(xiàn)類型實例中。在隨后的調(diào)用中,可以使用引用訪問外部存儲器和它包含的聚合上下文。外部存儲器通常應(yīng)在ODCIAggregateTerminate中釋放,在合并完成后,ODCIAggregateMerge釋放用于存儲合并上下文的外部內(nèi)存(ODCIAggregateMerge的第二個參數(shù))。
示例
聲明類中函數(shù)。
CREATE OR replace TYPE agg_test_schema_type_1 AUTHID CURRENT_USER AS OBJECT ( curr_str VARCHAR2 (32767), STATIC FUNCTION odciaggregateinitialize (sctx IN OUT agg_test_schema_type_1) RETURN NUMBER, MEMBER FUNCTION odciaggregateiterate (SELF IN OUT agg_test_schema_type_1,p1 IN VARCHAR2) RETURN NUMBER, MEMBER FUNCTION odciaggregateterminate (SELF IN agg_test_schema_type_1, returnvalue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER, MEMBER FUNCTION odciaggregatemerge (SELF IN OUT agg_test_schema_type_1, sctx2 IN agg_test_schema_type_1) RETURN NUMBER );
定義類中函數(shù)。
CREATE OR replace TYPE BODY agg_test_schema_type_1 IS STATIC FUNCTION odciaggregateinitialize (sctx IN OUT agg_test_schema_type_1) RETURN NUMBER IS BEGIN sctx := agg_test_schema_type_1(NULL); RETURN odciconst.success; END; MEMBER FUNCTION odciaggregateiterate ( SELF IN OUT agg_test_schema_type_1, 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 agg_test_schema_type_1, returnvalue OUT VARCHAR2, flags IN NUMBER ) RETURN NUMBER IS BEGIN returnvalue := curr_str; RETURN odciconst.success; END; MEMBER FUNCTION odciaggregatemerge ( SELF IN OUT agg_test_schema_type_1, sctx2 IN agg_test_schema_type_1 ) 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;
使用上面創(chuàng)建的類來創(chuàng)建自定義聚合函數(shù)并使用。
CREATE OR REPLACE FUNCTION agg_test_schema_func_1(p1 VARCHAR2) RETURN VARCHAR2 AGGREGATE USING agg_test_schema_type_1; create table agg_test_schema_table_1 (id int, c varchar2(100)); insert into agg_test_schema_table_1 values('1','a'); insert into agg_test_schema_table_1 values('1','b'); insert into agg_test_schema_table_1 values('2','b'); select id, agg_test_schema_func_1(c) from agg_test_schema_table_1 group by id; id | agg_test_schema_func_1 ----+------------------------ 2 | b 1 | a,b