自定义Oracle聚集函数:模拟SUM,MAX,AVG

实现三个函数,关键都在于处理ODCIAggregateIterate(),即下面几张图中的高亮部分。Oracle自定义聚集函数的功能很强大,笔者暂时只钻研到这一层。

f_sum(),模拟SUM()函数:

定义TYPE:

create or replace type f_sum_type2 as object (
  num number,
  static function ODCIAggregateInitialize(sctx In Out f_sum_type2) return number,
  member function ODCIAggregateIterate(self In Out f_sum_type2, value In number) return number,
  member function ODCIAggregateMerge(self In Out f_sum_type2, ctx2 In f_sum_type2) return number,
  member function ODCIAggregateTerminate(self In Out f_sum_type2, returnValue Out number, flags In number) return number
)

 定义TYPE BODY:

create or replace type body f_sum_type2
is

static function ODCIAggregateInitialize (sctx In Out f_sum_type2)
return number is
       begin
            sctx := f_sum_type2(0);
            return ODCIConst.Success;
       end;  
  
member function ODCIAggregateIterate (self In Out f_sum_type2, value In number)
return number is
       begin
            self.num := self.num + value;
            return ODCIConst.Success;
       end;
      
member function ODCIAggregateMerge(self In Out f_sum_type2, ctx2 In f_sum_type2)
return number is
       BEGIN
           self.num := self.num;
            return ODCIconst.Success;
       end;
      
member function ODCIAggregateTerminate(self In Out f_sum_type2, returnValue Out number, flags In number)
return number is
       begin
            returnValue := self.num;
            return ODCIConst.Success;
       end;

end;

 定义函数:

CREATE OR REPLACE FUNCTION f_sum2(input number )
RETURN number
PARALLEL_ENABLE AGGREGATE USING f_sum_type2;

 

 测试:

SQL> select f_sum2(id),sum(id) from "tblabc"
  2  ;

F_SUM2(ID)    SUM(ID)
---------- ----------
      5247       5247

SQL>

 

f_max(),模拟MAX()函数:

定义TYPE:

CREATE OR REPLACE TYPE f_max_type AS OBJECT
(
 var NUMBER,
 STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT f_max_type) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateIterate(SELF IN OUT f_max_type, VALUE IN NUMBER) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT f_max_type, ctx2 IN OUT f_max_type) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT f_max_type, returnValue OUT NUMBER, flags IN NUMBER) RETURN NUMBER
 
)

 

 定义TYPE BODY:

CREATE OR REPLACE TYPE BODY f_max_type IS
      
       STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT f_max_type)
       RETURN NUMBER IS
              BEGIN
                   sctx := f_max_type(0);
                   RETURN ODCIConst.Success;
              END;
             
       MEMBER FUNCTION ODCIAggregateIterate(SELF IN OUT f_max_type, VALUE IN NUMBER)
       RETURN NUMBER IS
              BEGIN
                   IF SELF.var < VALUE THEN
                      SELF.var := VALUE;
                   END IF;

                   RETURN ODCIConst.Success;
              END;
             
       MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT f_max_type, ctx2 IN OUT f_max_type)
       RETURN NUMBER IS
              BEGIN
                   RETURN ODCIConst.Success;
              END;
             
       MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT f_max_type, returnValue OUT NUMBER, flags IN NUMBER)
       RETURN NUMBER IS
              BEGIN
                   returnValue := SELF.var;
                   RETURN ODCIconst.success;
              END;
      
END;

 

 

CREATE OR REPLACE FUNCTION f_max (input NUMBER)
RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING f_max_type;

 

SQL> select f_max(id),max(id) from "tblabc"
  2  ;

 F_MAX(ID)    MAX(ID)
---------- ----------
       303        303

SQL>

f_avg(),模拟AVG()函数:

定义TYPE:

CREATE OR REPLACE TYPE f_avg_type AS OBJECT
(
 SUM NUMBER, num NUMBER,
 STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT f_avg_type) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateIterate(SELF IN OUT f_avg_type, VALUE IN NUMBER) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateMerge(SELF IN OUT f_avg_type, ctx2 IN f_avg_type) RETURN NUMBER,
 MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT f_avg_type, returnValue OUT NUMBER, flags IN NUMBER) RETURN NUMBER
)

  定义TYPE BODY:

CREATE OR REPLACE TYPE BODY f_avg_type
IS

STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT f_avg_type)
RETURN NUMBER IS
       BEGIN
            sctx := f_avg_type(0, 0);
            RETURN ODCICONST.Success;
       END;
      
MEMBER FUNCTION ODCIAggregateIterate (SELF IN OUT f_avg_type, VALUE IN NUMBER)
RETURN NUMBER IS
       BEGIN
            SELF.SUM := SELF.SUM + VALUE;
            SELF.num := SELF.num + 1;

            RETURN ODCIConst.Success;
       END;
      
MEMBER FUNCTION ODCIaggregateMerge(SELF IN OUT f_avg_type, ctx2 IN f_avg_type)
RETURN NUMBER IS
       BEGIN
            RETURN ODCIConst.Success;
       END;
      
MEMBER FUNCTION ODCIAggregateTerminate(SELF IN OUT f_avg_type, returnValue OUT NUMBER, flags IN NUMBER)
RETURN NUMBER IS
       BEGIN
            returnValue := SELF.SUM/SELF.num;
            RETURN ODCIConst.Success;
       END;
      
END;

 定义函数:

CREATE OR REPLACE FUNCTION f_avg(input NUMBER)
RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING f_avg_type;

 测试:

SQL> select f_avg(id),avg(id) from "tblabc"
  2  ;

 F_AVG(ID)    AVG(ID)
---------- ----------
276.157895 276.157895

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值