`
piperzero
  • 浏览: 3471385 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

自定义聚集函数

 
阅读更多

自定义聚集函数接口简介

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

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

通过实现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(sctxIN OUTstring_agg_type ) return number

自定义聚集函数初始化操作,从这儿开始一个聚集函数。初始化的聚集环境(aggregation context)会以对象实例(object typeinstance)传回给oracle.

b. member function ODCIAggregateIterate(selfIN OUT string_agg_type ,value IN varchar2) return number

自定义聚集函数,最主要的步骤,这个函数定义我们的聚集函数具体做什么操作,后面的例子,是取最大值,最小值,平均值,还是做连接操作.self为当前聚集函数的指针,用来与前面的计算结果进行关联

这个函数用来遍历需要处理的数据,被oracle重复调用。每次调用的时候,当前的aggreation context和 新的(一组)值会作为传入参数。 这个函数会处理这些传入值,然后返回更新后的aggregation context.这个函数对每一个NON-NULL的值都会被执行一次。NULL值不会被传递个聚集函数。

c. member function ODCIAggregateMerge (selfIN string_agg_type,returnValue OUTvarchar2,flags IN number) return number

用来合并两个聚集函数的两个不同的指针对应的结果,用户合并不同结果结的数据,特别是处理并行(parallel)查询聚集函数的时候.

这个函数用来把两个aggregation context整合在一起,一般用来并行计算中(当一个函数被设置成enable parallel处理的时候)。

d. member functionOCDIAggregateTerminate(self IN string_agg_type,returnValue OUT varchar2,flagsIN number)

终止聚集函数的处理,返回聚集函数处理的结果.

这个函数是Oracle调用的最后一个函数。它接收aggregation context作为参数,返回最后的aggregatevalue.

应用场景一:字符串聚集

CREATE OR REPLACE TYPE typ_concatenate_impl AS OBJECT

(

retstr VARCHAR2(30000),--拼凑使用的中间字符串

SEPARATORFLAGVARCHAR2(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自定义聚集函数的使用 。

    聚集函数(自定义分隔符拼接字符串)

    自定义聚集函数拼接字符串,根据网上常见的例子加以改进,可以自定义分隔符(利用的自定义type)。

    Oracle10g自定义聚合函数(字符串拼接)

    * 自定义聚合函数 wmsys.wm_concat 替换办法 * 超大字符串拼接,单个字符串4000、分隔符100... * Oracle11g Release2版本引入了LISTAGG 函数,使得聚集连接字符串变得很容易。并且允许使用我们指定连接串中的字段顺序

    ORACLE 乘积 聚集

    使用自定义聚集函数,实现聚集乘积: 测试select id,fun_multiply(t.value) "乘积" from (select 3 id , 4 value from dual union select 1 id , 1 value from dual union select 1 id , 0 value from dual ...

    chiral_gnn

    手性感知消息传递网络具有四面体手性的分子的自定义聚集函数( )要求python(版本> = 3.7) pytorch(版本> = 1.14) rdkit(版本> = 2020.03.2) pytorch-geometric(版本> = 1.6.0)安装首先,克隆存储库: git ...

    HQL:Hibernate Qusery Language

    HQL:Hibernate Qusery Language HQL :是面向对象的查询语言,同SQL有些相似是Hib中最常用的方式。...提供内制的聚集函数,sum(),min(),max() 能调用用户的自定义SQL 支持子查询,嵌入式查询 支持动态绑定参数

    HSORT分类信息 v4.1.rar

    系统使用DIV CSS设计,信息函数库开放,只需要有基础的设计能力,便可以自由调用函数,设计自己的站点。 ·支持栏目分类更标准 在研究多个站点的分类信息系统后,我们设置了目前的一套分类标准,并且支持自定义...

    mssql 30万条数据 搜索文本字段的各种方式对比

    数据库: 30万条,有ID列但无主键,在要搜索的“分类”字段上建有非聚集索引 过程T-SQL: 代码如下: /* 用户自定义函数:执行时间在1150-1200毫秒左右 CREATE FUNCTION [dbo].[gethl] (@types nvarchar(4)) RETURNS ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例252 自定义最大化、最小化和关闭按钮 321 实例253 禁止改变窗体的大小 323 11.3 设置窗体的标题栏 324 实例254 指定窗体标题栏图标 324 实例255 拖动没有标题栏的窗体 325 实例256 取消窗体标题栏与边框 326 ...

    Visual C++程序开发范例宝典(光盘) 第四部分

    实例260 利用聚集函数COUNT求日销售额大于某值的商品数 9.9 多表查询 实例261 利用FROM子句进行多表查询 实例262 合并多个结果集 9.10 嵌套查询 实例263 简单嵌套查询 实例264 复杂嵌套查询 9.11 子查询 ...

    Visual C++程序开发范例宝典(光盘) 第八部分

    实例260 利用聚集函数COUNT求日销售额大于某值的商品数 9.9 多表查询 实例261 利用FROM子句进行多表查询 实例262 合并多个结果集 9.10 嵌套查询 实例263 简单嵌套查询 实例264 复杂嵌套查询 9.11 子查询 ...

    PHP程序开发范例宝典III

    实例227 使用聚集函数First或Last求数据表中第一条或最后一条记录 352 8.10 多表查询 354 实例228 使用select语句进行多表查询 354 实例229 使用表的别名 355 实例230 合并多个结果集 356 8.11 嵌套查询...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例079 自定义函数截取中文字符串 113 实例080 公告标题的截取 114 实例081 论坛内容的简短输出 116 实例082 自定义函数过滤字符串 117 2.8 字符串 118 实例083 过滤论坛帖子中的空白和特殊字符 118 实例084 对论坛...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例079 自定义函数截取中文字符串 113 实例080 公告标题的截取 114 实例081 论坛内容的简短输出 116 实例082 自定义函数过滤字符串 117 2.8 字符串 118 实例083 过滤论坛帖子中的空白和特殊字符 118 实例084 对论坛...

    Visual C++程序开发范例宝典(PDF扫描版).part3

     cc实例260 利用聚集函数COUNT求日销售额大于某值的商品数   9.9 多表查询   cc实例261 利用FROM子句进行多表查询   cc实例262 合并多个结果集   9.10 嵌套查询   cc实例263 简单嵌套查询   cc...

    Visual C++程序开发范例宝典(PDF扫描版).part2

     cc实例260 利用聚集函数COUNT求日销售额大于某值的商品数   9.9 多表查询   cc实例261 利用FROM子句进行多表查询   cc实例262 合并多个结果集   9.10 嵌套查询   cc实例263 简单嵌套查询   cc...

    Visual C++ 程序开发范例宝典 源码 光盘 part2

    cc实例258 利用聚集函数SUM对销售额进行汇总 cc实例259 利用聚集函数AVG求某班学生的平均年龄 cc实例260 利用聚集函数COUNT求日销售额大于某值的商品数 9.9 多表查询 cc实例261 利用FROM子句进行多表查询 ...

Global site tag (gtag.js) - Google Analytics