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。
a. static function ODCIAggregateInitialize(sctx IN OUTstring_agg_type ) return number
自定义聚集函数初始化操作,从这儿开始一个聚集函数。初始化的聚集环境(aggregation context)会以对象实例(object type instance)传回给oracle.
b. member function ODCIAggregateIterate(self IN OUT string_agg_type ,value IN varchar2) return number
自定义聚集函数,最主要的步骤,这个函数定义我们的聚集函数具体做什么操作,后面的例子,是取最大值,最小值,平均值,还是做连接操作.self 为当前聚集函数的指针,用来与前面的计算结果进行关联
这个函数用来遍历需要处理的数据,被oracle重复调用。每次调用的时候,当前的aggreation context 和 新的(一组)值会作为传入参数。 这个函数会处理这些传入值,然后返回更新后的aggregation context. 这个函数对每一个NON-NULL的值都会被执行一次。NULL值不会被传递个聚集函数。
c. member function ODCIAggregateMerge (self IN string_agg_type,returnValue OUT varchar2,flags IN number) return number
用来合并两个聚集函数的两个不同的指针对应的结果,用户合并不同结果结的数据,特别是处理并行(parallel)查询聚集函数的时候.
这个函数用来把两个aggregation context整合在一起,一般用来并行计算中(当一个函数被设置成enable parallel 处理的时候)。
d. member function OCDIAggregateTerminate(self IN string_agg_type,returnValue OUT varchar2,flags IN number)
终止聚集函数的处理,返回聚集函数处理的结果.
这个函数是Oracle调用的最后一个函数。它接收aggregation context作为参数,返回最后的aggregate value.
应用场景一:字符串聚集
|
CREATE OR REPLACE TYPE typ_concatenate_impl AS OBJECT ( retstr VARCHAR2(30000), --拼凑使用的中间字符串 SEPARATORFLAG VARCHAR2(64), --分隔符,默认用自由定义|,可以修改此处 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.SEPARATORFLAG; RETURN ODCICONST.SUCCESS; END; --定义终止聚集函数的处理,返回聚集函数处理的结果 MEMBER FUNCTION ODCIAGGREGATETERMINATE(self IN typ_concatenate_impl, returnvalue OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS BEGIN IF returnvalue IS NOT NULL THEN returnvalue := SUBSTR(self.retstr,1,LENGTH(self.retstr)-1); ELSE returnvalue := self.retstr; END IF; 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; |
查看执行后的结果,并与WMSYS.WM_CONCAT函数执行效果对照。
|
SQL> SELECT id,f_concatenate_str(name) name FROM test GROUP BY id; ID NAME ---------- ------------------------------------------------------------------ 1 AAA,ABC, 2 BBB,DDD, 3 CCC, SQL> SELECT id,wmsys.wm_concat(name) name FROM test GROUP BY id; ID NAME ---------- ------------------------------------------------------------------ 1 AAA,ABC 2 BBB,DDD 3 CCC SQL> SELECT id,f_concatenate_str(name) OVER (PARTITION BY id) name FROM test; ID NAME ---------- ------------------------------------------------------------------ 1 AAA,ABC, 1 AAA,ABC, 2 DDD,BBB, 2 DDD,BBB, 3 CCC, SQL> SELECT id,wmsys.wm_concat(name) OVER (PARTITION BY id) name FROM test; ID NAME ---------- ------------------------------------------------------------------ 1 AAA,ABC 1 AAA,ABC 2 DDD,BBB 2 DDD,BBB 3 CCC |
实际上在Oracle10g版本中提供了一个未文档化的函数wmsys.wm_concat(),也可以实现字符串的聚集拼接;这两个函数异曲同工。
这也说明Oracle提供的聚集函数已足够强大,想发明不重复的轮子还是很困难的。
Oracle自定义聚集函数的更多相关文章
- oracle 自定义 聚合函数
Oracle自定义聚合函数实现字符串连接的聚合 create or replace type string_sum_obj as object ( --聚合函数的实质就是一个对象 sum ...
- ORACLE 自定义聚合函数
用户可以自定义聚合函数 ODCIAggregate,定义了四个聚集函数:初始化.迭代.合并和终止. Initialization is accomplished by the ODCIAggrega ...
- oracle 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值
create or replace function MAX_O3_8HOUR_ND(value NUMBER) return NUMBER parallel_enable aggregate usi ...
- 【Oracle】Oracle自定义的函数与过程
本篇主要内容如下: 6.1 引言 6.2 创建函数 6.3 存储过程 6.3.1创建过程 6.3.2调用存储过程 6.3.3 AUTHID 6.3.4 PRAGMA AUTONOMOUS_TRANSA ...
- Oracle自定义脱敏函数
对于信息安全有要求的,在数据下发和同步过程中需要对含有用户身份信息的敏感字段脱敏,包括用户姓名.证件号.地址等等,下面是自定义函数的代码 CREATE OR REPLACE FUNCTION F_GE ...
- Oracle 自定义实用函数
一.ctod 字符转为date, create or replace function ctod(str in varchar2) return date as begin return to_dat ...
- 重写Oracle的wm_concat函数,自定义分隔符、排序
oracle中,wm_concat函数是一个聚合函数,和mysql中的group_concat函数类似,不过group_concat函数比较强大,可以定义分隔符和排序,当然所谓强大是相对的,这里假使我 ...
- Oracle自定义函数1
用户定义函数是存储在数据库中的代码块,可以把值返回到调用程序.调用时如同系统函数一样,如max(value)函数,其中,value被称为参数.函数参数有3种类型. IN 参数类型:表示输入给函数的参数 ...
- Oracle自定义函数
核心提示:函数用于返回特定数据.执行时得找一个变量接收函数的返回值; 语法如下: create or replace function function_name ( argu1 [mode1] da ...
随机推荐
- ASP.Net中后台控制页面提示信息的显示方式
ASP.Net中后台控制页面提示信息的显示方式 用于删除或修改成功后的显示:(背景No空白) ScriptManager.RegisterStartupScript(this, typeof(Pa ...
- linux 源码安装 Nginx
1.安装前环境准备安装make:# yum -y install gcc automake autoconf libtool make安装g++:# yum install gcc gcc-c++ 2 ...
- C#基础—不安全代码(unsafe code)
1.为何要有unsafe 也许是为了实现CLR类型安全的目标吧,默认情况下,C#没有提供指针的使用算法,但是有些情况下也可能需要指针这样直接访问内存的东西(虽然目前我还没有用过),但是有时候程序员非常 ...
- C++多态有哪几种方式?
C++多态方式: (1)静态多态(重载,模板) 是在编译的时候,就确定调用函数的类型. (2)动态多态(覆盖,虚函数实现) 在运行的时候,才确定调用的是哪个函数,动态绑定.运行基类指针指向派生类的对象 ...
- ubuntu学习教程
1:搜狗输入法安装: http://jingyan.baidu.com/article/adc815134f4b92f722bf7350.html 2:flash插件的安装: http://jingy ...
- Java数据结构和算法(一):简介
本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...
- Atitit.软件仪表盘(2)--vm子系统--资源占用监测
Atitit.软件仪表盘(2)--vm子系统--资源占用监测 1. Jvisualvm.exe 2. jprofile 3. Heap //permgen monitor 作者::老哇的爪子At ...
- atitit.窗体静听esc退出本窗体java swing c# .net php
atitit.窗体静听esc退出本窗体java swing c# .net php 1. 监听esc 按键 1 1.1. 监听一个组件 1 1.2. 监听加在form上 1 2. 关闭窗体 2 1. ...
- [POJ 1236][IOI 1996]Network of Schools
Description A number of schools are connected to a computer network. Agreements have been developed ...
- rabbitMQ之安装和配置(一)
前言 erlang是一门面向并发的编程语言,流行的消息队列rabbitMQ是基于erlang环境运行的: 下载安装erlang语言环境 源码安装 # 从官网下载,在任何目录下,使用root权限 wge ...