• Oracle深入之自定义聚合函数(字符串数组去重,统计子串个数)


    一、概述

    Oracle提供了很多预定义好的聚集函数,比如Max(), Sum(), AVG(), 但是这些预定义的聚集函数基本上都是适应于标量数据(scalar data), 对于复杂的数据类型,比如说用户自定义的Object type, Clob等, 是不支持的。

    但是,用户可以通过实现Oracle的Extensibility Framework中的ODCIAggregate interface来创建自定义聚集函数,而且自定义的聚集函数跟内建的聚集函数用法上没有差别。

    通过实现 ODCIAggregate rountines来创建自定义的聚集函数。可以通过定义一个对象类型(Object Type),然后在这个类型内部实现ODCIAggregate 接口函数(routines), 可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++, JAVA, PL/SQL等。在这个Object Type定义之后,相应的接口函数也都在该Object Type Body内部实现之后, 就可以通过CREATE FUNCTION语句来创建自定义的聚集函数了。

    每个自定义的聚集函数需要实现4个ODCIAggregate 接口函数, 分别是:、迭代、合并和终止。这些函数定义了任何一个聚集函数内部需要实现的操作,这些函数分别是 初始化(initialization), 迭代(iteration), 合并(merging) 和 终止(termination)。

    函数描述
    ODCIAggregateInitializeOracle 调用此例程来初始化用户定义聚合的计算。初始化的聚合上下文作为对象类型实例传回 Oracle。
    ODCIAggregateIterateOracle 反复调用此例程。每次调用时,都会传递一个新值(或一组新值)作为输入。当前的聚合上下文也被传入。例程处理新值并将更新的聚合上下文返回给 Oracle。NULL为基础组中的每个非值调用此例程。(NULL值在聚合期间被忽略,并且不传递给例程。)
    ODCIAggregateMergeOracle 调用此例程来组合两个聚合上下文。该例程将两个上下文作为输入,将它们组合起来,然后返回一个聚合上下文。
    ODCIAggregateTerminateOracle 调用此例程作为聚合的最后一步。该例程将聚合上下文作为输入并返回结果聚合值。

    二、使用

    本例子是利用数组去重,统计一个字段中不同子串的个数

    1.创建数组(Type)

    --创建数组对象
    CREATE OR REPLACE TYPE "TYPE_STR" is table of varchar2(255);
    
    • 1
    • 2

    2.创建自定义对象(OBJECT Type)

    --创建自定义对象
    CREATE OR REPLACE TYPE Count_Substr_Type AS OBJECT
    (
      --用户自定义的参数,按顺序从上到下,初始化则是从左到右:Count_Substr_Type(to_clob(','),',',TYPE_STR())
      
      --字符串值
      concat_str CLOB,
      
      --分割符号
      splitstr varchar2(64),
      
      --自定义变量,字符串数组,初始化为空数组
      str_array TYPE_STR,
      
    --ODCIAggregateInitialize做一些初始化操作
    
      STATIC FUNCTION ODCIAggregateInitialize(cs_ctx In Out Count_Substr_Type)
        return number,
    
    --ODCIAggregateIterate是主要的处理逻辑所在,这里定义一个迭代操作
    
      member function ODCIAggregateIterate(self     In Out Count_Substr_Type,
                                           curvalue in VARCHAR2) return number,
    
    -- ODCIAggregateMerge是一个合并函数,如果在使用时指定了partition enabled,就必须定义此函数,用来把并行处理的结果进行合并
    
      member function ODCIAggregateMerge(self In Out Count_Substr_Type,
                                         ctx2 In Out Count_Substr_Type)
        return number,
    
    --ODCIAggregateTerminate是一个终止函数,顾名思义,在这个函数中对结果做最后处理并返回
    
      member function ODCIAggregateTerminate(self        In Out Count_Substr_Type,
                                             returnValue Out number,
                                             flags       IN NUMBER)
        return number
    
    )
    /
    
    --创建自定义对象体
    CREATE OR REPLACE TYPE BODY Count_Substr_Type IS
    
      --初始化
      STATIC FUNCTION ODCIAggregateInitialize(cs_ctx IN OUT Count_Substr_Type)
        return NUMBER IS
      BEGIN
        --初始化参数   
        cs_ctx := Count_Substr_Type(to_clob(','),',',TYPE_STR());
        RETURN ODCICONST.SUCCESS;
      
      END;
    
      -- 迭代 ,利用数组去重
      member FUNCTION ODCIAggregateIterate(self     IN OUT Count_Substr_Type,
                                           curvalue IN VARCHAR2) return NUMBER IS
        sub_str   varchar2(500);
        all_len   number ;
        p_len     number ;
        s_len     number ;
      begin
      
         all_len  := length(curvalue);
         s_len:=1;
         p_len:=1;
         sub_str:='';
        while s_len <= all_len loop
           
            p_len := instr(curvalue, splitstr, s_len);
            if p_len = 0 then
              p_len := all_len;
              sub_str := substr(curvalue, s_len);
            else
              sub_str := substr(curvalue, s_len, p_len - s_len);
            end if;
            s_len   := p_len + 1;
           
            if sub_str MEMBER of self.str_array then
              continue;
            else
              self.str_array.extend;
              self.str_array(self.str_array.count):= sub_str;
            end if;
          
          end loop;
        RETURN ODCICONST.SUCCESS;
      
      END;
      
      --合并,可用与并发操作
      member FUNCTION ODCIAggregateMerge(self IN OUT Count_Substr_Type,
                                         ctx2 IN OUT Count_Substr_Type)
        return NUMBER IS
      BEGIN
        
        RETURN ODCICONST.SUCCESS;
      
      END;
      
      --终止,返回数组个数
      member FUNCTION ODCIAggregateTerminate(self        IN OUT Count_Substr_Type,
                                             returnValue OUT number,
                                             flags       IN NUMBER) return NUMBER IS
      BEGIN
      
      
        returnValue:=self.str_array.count;
      
        RETURN ODCICONST.SUCCESS;
      
      END;
    
    END;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114

    3.创建自定义函数(Function)

    CREATE OR REPLACE FUNCTION Count_Substr (in_str clob) RETURN number AGGREGATE USING Count_Substr_Type;
    
    • 1

    4.使用示例

    select count_substr('PA001,PA002,PA005,PA003,PA003,PA003,PA001') from dual;
    >> 4
    
    • 1
    • 2

    参考文档

    [1].User-Defined Aggregate Functions
    [2].Oracle自定义聚集函数

  • 相关阅读:
    【无标题】
    Spring AOP
    java真实面试(南京中软国际)
    33.反射
    ChatGPT作者John Schulman:我们成功的秘密武器
    linux常见命令记录
    bootstrap系列-2.css排版
    QT聊天室阶段性记录(完善中:注册功能,数据库存储)
    nginx入门
    Mongodb安全访问控制操作案例
  • 原文地址:https://blog.csdn.net/qq_18913129/article/details/124965454