今天工作中看见别人写的自定义聚集函数,所以一门心思的想搞懂,就在网上找资料了。

自定义聚集函数

自定义聚集函数接口简介

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自定义聚集函数的更多相关文章

  1. oracle 自定义 聚合函数

    Oracle自定义聚合函数实现字符串连接的聚合   create or replace type string_sum_obj as object ( --聚合函数的实质就是一个对象      sum ...

  2. ORACLE 自定义聚合函数

    用户可以自定义聚合函数  ODCIAggregate,定义了四个聚集函数:初始化.迭代.合并和终止. Initialization is accomplished by the ODCIAggrega ...

  3. oracle 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值

    create or replace function MAX_O3_8HOUR_ND(value NUMBER) return NUMBER parallel_enable aggregate usi ...

  4. 【Oracle】Oracle自定义的函数与过程

    本篇主要内容如下: 6.1 引言 6.2 创建函数 6.3 存储过程 6.3.1创建过程 6.3.2调用存储过程 6.3.3 AUTHID 6.3.4 PRAGMA AUTONOMOUS_TRANSA ...

  5. Oracle自定义脱敏函数

    对于信息安全有要求的,在数据下发和同步过程中需要对含有用户身份信息的敏感字段脱敏,包括用户姓名.证件号.地址等等,下面是自定义函数的代码 CREATE OR REPLACE FUNCTION F_GE ...

  6. Oracle 自定义实用函数

    一.ctod 字符转为date, create or replace function ctod(str in varchar2) return date as begin return to_dat ...

  7. 重写Oracle的wm_concat函数,自定义分隔符、排序

    oracle中,wm_concat函数是一个聚合函数,和mysql中的group_concat函数类似,不过group_concat函数比较强大,可以定义分隔符和排序,当然所谓强大是相对的,这里假使我 ...

  8. Oracle自定义函数1

    用户定义函数是存储在数据库中的代码块,可以把值返回到调用程序.调用时如同系统函数一样,如max(value)函数,其中,value被称为参数.函数参数有3种类型. IN 参数类型:表示输入给函数的参数 ...

  9. Oracle自定义函数

    核心提示:函数用于返回特定数据.执行时得找一个变量接收函数的返回值; 语法如下: create or replace function function_name ( argu1 [mode1] da ...

随机推荐

  1. PHP代码优化之细节优化(转)

    PHP 独特的语法混合了 C.Java.Perl 以及 PHP 自创新的语法.它可以比 CGI或者Perl更快速的执行动态网页.用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML ...

  2. tomcat发布web项目,支持域名

    首先需要安装JDK,不是Linux自带的OpenJDK,参考下面的文章: centos下 安装jdk 设置java环境变量:编辑这个/etc/profile文件: export JAVA_HOME=/ ...

  3. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

  4. DataGridView 的单元格的边框、 网格线样式的设定

    1) DataGridView 的边框线样式的设定DataGridView 的边框线的样式是通过 DataGridView.BorderStyle 属性来设定的. BorderStyle 属性设定值是 ...

  5. 构造矩阵解决这个问题 【nyoj299 Matrix Power Series】

    矩阵的又一个新使用方法,构造矩阵进行高速幂. 比方拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s. ...

  6. 解决 scrapy 爬虫出现Forbidden by robots.txt

    我们在爬取网站的时候,scrapy  默认的是遵循  robots.txt 协议,怎么破解这个文件 操作很简单,找到setting 文件 直接改成

  7. connect: Network is unreachable解決方法

    connect: Network is unreachable解決方法   解決方式:請確認ifcfg-eth0檔案設定 指令如下:   vi /etc/sysconfig/network-scrip ...

  8. MySQL多线程同步-Transfer使用测试

    由淘宝核心系统研发—数据库组开发的MySQL-Transfer,用于解决MySQL主从同步延迟的问题,从MySQL单线程到多线程的工作模式.可以观看@丁奇的相关资料: MySQL多线程同步-Trans ...

  9. MYSQL数据库的导出的几种方法

    mysql的数据导出几种方法   从网上找到一些问题是关于如何从MySQL中导出数据,以便用在本地或其它的数据库系统之上:以及 将现有数据导入MySQL数据库中. 数据导出 数据导出主要有以下几种方法 ...

  10. Wireshark-TCP协议分析(包结构以及连接的建立和释放)

    原文:http://blog.csdn.net/ahafg/article/details/51039584 TCP:传输控制协议 TCP是一种面向连接的.可靠的.基于字节流的传输层通信协议.  面向 ...