[Oracle Data Cartridge Interface] User-Defined Aggregation Functions
2009-12-28 14:29
381 查看
本文基本上是对Orace文档(http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14289/dciaggfns.htm#sthref542)的翻译。
Oracle提供了很多预定义好的聚集函数,比如Max(),Sum(),AVG(),但是这些预定义的聚集函数基本上都是适应于标量数据(scalardata),对于复杂的数据类型,比如说用户自定义的Objecttype,Clob等,是不支持的。
但是,幸运的是,用户可以通过实现Oracle的ExtensibilityFramework中的ODCIAggregateinterface来创建自定义聚集函数,而且自定义的聚集函数跟内建的聚集函数用法上没有差别。
ODCI是OracleDataCartridgeInterface几个单词的首字母缩写,关于OracleDataCartridge,可以参见这里。
1.OverviewofUser-DefinedAggregateFunctions
通过实现ODCIAggregaterountines来创建自定义的聚集函数。可以通过定义一个对象类型(ObjectType),然后在这个类型内部实现ODCIAggregate接口函数(routines),可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++,JAVA,PL/SQL等。在这个ObjectType定义之后,相应的接口函数也都在该ObjectTypeBody内部实现之后,就可以通过CREATEFUNCTION语句来创建自定义的聚集函数了。
每个自定义的聚集函数需要实现4个ODCIAggregate接口函数,这些函数定义了任何一个聚集函数内部需要实现的操作,这些函数分别是initialization,iteration,merging和termination。
(1)ODCIAggregateInitialize这个函数用来执行初始化操作(initialization).Oracle会调用这个函数来初始化自定义函数计算。初始化的聚集环境(aggregationcontext)会以对象实例(objecttypeinstance)传回给oracle.
(2)ODCIAggregateIterate这个函数用来遍历需要处理的数据,被oracle重复调用。每次调用的时候,当前的aggreationcontext和新的(一组)值会作为传入参数。这个函数会处理这些传入值,然后返回更新后的aggregationcontext.这个函数对每一个NON-NULL的值都会被执行一次。NULL值不会被传递个聚集函数。
(3)ODCIAggregateMerge这个函数用来把两个aggregationcontext整合在一起,一般用来并行计算中(当一个函数被设置成enableparallel处理的时候)。
(4)ODCIAggregateTerminate这个函数是Oracle调用的最后一个函数。它接收aggregationcontext作为参数,返回最后的aggregatevalue.
Example:自定义聚集函数是如何工作的
为了完成求平均值的计算,AVG函数经历下面几个步骤:
(1)Initializes:初始化AggregationContext:
runningSum=0;runningCount=0;
(2)Iteratively处理每个连续的输入,同时更新aggregationcontext:
runningSum+=inputval;runningCount++;
(3)【这步是可选的】Merge整合两个aggregationcontext返回一个aggregationcontext.如果需要这一步的话,它是在termination之前执行。
runningSum=runningSum1+runningSum2;
runningCount=runningCount1+runningCount2;
(4)Terminates计算出最后的结果,通过最后的aggregationcontext来返回最后的aggregatedvalue.
return(runningSum/runningCount);
如果AVG是自定义的聚集函数的话,与之相对应的对象类型(objecttype)需要实现对应的ODCIAggregate的接口函数。变量runningSum和runningCount是对象类型中的属性(attribute).
2.CreatingaUser-DefinedAggregate
创建一个自定义聚集函数分成两步:如下面两个例子所示:
Example:如何实现ODCIAggregate接口:
Example:如何定义自定义聚集函数:
注意在定义函数的时候需要通过AggregateUsing语句来关联上对应的实现了ODCIAggregate接口的ObjectType。
3.UsingaUser-DefinedAggregate
自定义的聚集函数可以像内置的聚集函数一样使用,可以用在SELECT,ORDERBY,HAVING语句中。下面几个例子说明如何使用上面定义的自定义函数SpatialUnion
Example:用在Select语句中
Example:用在Having语句中,
Example:其他
自定义聚集函数可以跟All,Distinct一起使用,亦可以用在Groupby的扩展语句中,像ROLLUP,CUBE,groupingsets.
4.EvaluatingUser-DefinedAggregatesinParallel
跟内置的聚集函数一样,自定义的聚集函数也可以并行来处理,如下图
需要注意的是,自定义的聚集函数需要声明为parallel-enabled,如下
5.User-DefinedAggregatesandAnalyticFunctions
自定义的聚集函数可以被当做Analytic函数来用,
6.ReusingtheAggregationContextforAnalyticFunctions
当一个自定义的聚集函数被用来做AnalyticFunction的时候,对每条记录对应的window都会计算一次aggregate。一般的说来,每个连续的窗口包含大部分相同的数据集合。
可以通过实现ODCIAggregateDelete接口函数来让Oracle更有效地复用aggregationcontext.
7.AncompleteexampleforCreatingandUsingaUser-DefinedAggregateFunction
SecondMax()返回一组数里面第二大的那个值。
(1)实现类型SecondMaxImpl,该类型包含了ODCIAggregate接口函数,
(2).实现类型SecondMaxImpl的body,
(3).创建自定义聚集函数SecondMax()
(4).使用自定义聚集函数SecondMax()
Oracle提供了很多预定义好的聚集函数,比如Max(),Sum(),AVG(),但是这些预定义的聚集函数基本上都是适应于标量数据(scalardata),对于复杂的数据类型,比如说用户自定义的Objecttype,Clob等,是不支持的。
但是,幸运的是,用户可以通过实现Oracle的
ODCI是OracleDataCartridgeInterface几个单词的首字母缩写,关于OracleDataCartridge,可以参见
1.OverviewofUser-DefinedAggregateFunctions
通过实现ODCIAggregaterountines来创建自定义的聚集函数。可以通过定义一个对象类型(ObjectType),然后在这个类型内部实现ODCIAggregate接口函数(routines),可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++,JAVA,PL/SQL等。在这个ObjectType定义之后,相应的接口函数也都在该ObjectTypeBody内部实现之后,就可以通过CREATEFUNCTION语句来创建自定义的聚集函数了。
每个自定义的聚集函数需要实现4个ODCIAggregate接口函数,这些函数定义了任何一个聚集函数内部需要实现的操作,这些函数分别是initialization,iteration,merging和termination。
(1)ODCIAggregateInitialize这个函数用来执行初始化操作(initialization).Oracle会调用这个函数来初始化自定义函数计算。初始化的聚集环境(aggregationcontext)会以对象实例(objecttypeinstance)传回给oracle.
(2)ODCIAggregateIterate这个函数用来遍历需要处理的数据,被oracle重复调用。每次调用的时候,当前的aggreationcontext和新的(一组)值会作为传入参数。这个函数会处理这些传入值,然后返回更新后的aggregationcontext.这个函数对每一个NON-NULL的值都会被执行一次。NULL值不会被传递个聚集函数。
(3)ODCIAggregateMerge这个函数用来把两个aggregationcontext整合在一起,一般用来并行计算中(当一个函数被设置成enableparallel处理的时候)。
(4)ODCIAggregateTerminate这个函数是Oracle调用的最后一个函数。它接收aggregationcontext作为参数,返回最后的aggregatevalue.
Example:自定义聚集函数是如何工作的
SELECTAVG(T.Sales)
FROMAnnualSalesT
GROUPBYT.State;
为了完成求平均值的计算,AVG函数经历下面几个步骤:
(1)Initializes:初始化AggregationContext:
runningSum=0;runningCount=0;
(2)Iteratively处理每个连续的输入,同时更新aggregationcontext:
runningSum+=inputval;runningCount++;
(3)【这步是可选的】Merge整合两个aggregationcontext返回一个aggregationcontext.如果需要这一步的话,它是在termination之前执行。
runningSum=runningSum1+runningSum2;
runningCount=runningCount1+runningCount2;
(4)Terminates计算出最后的结果,通过最后的aggregationcontext来返回最后的aggregatedvalue.
return(runningSum/runningCount);
如果AVG是自定义的聚集函数的话,与之相对应的对象类型(objecttype)需要实现对应的ODCIAggregate的接口函数。变量runningSum和runningCount是对象类型中的属性(attribute).
2.CreatingaUser-DefinedAggregate
创建一个自定义聚集函数分成两步:如下面两个例子所示:
Example:如何实现ODCIAggregate接口:
CREATETYPESpatialUnionRoutines(
STATICFUNCTIONODCIAggregateInitialize(...)...,
MEMBERFUNCTIONODCIAggregateIterate(...)...,
MEMBERFUNCTIONODCIAggregateMerge(...)...,
MEMBERFUNCTIONODCIAggregateTerminate(...)
);
CREATETYPEBODYSpatialUnionRoutinesIS
...
END;
Example:如何定义自定义聚集函数:
CREATEFUNCTIONSpatialUnion(xGeometry)RETURNGeometry
AGGREGATEUSINGSpatialUnionRoutines;
注意在定义函数的时候需要通过AggregateUsing语句来关联上对应的实现了ODCIAggregate接口的ObjectType。
3.UsingaUser-DefinedAggregate
自定义的聚集函数可以像内置的聚集函数一样使用,可以用在SELECT,ORDERBY,HAVING语句中。下面几个例子说明如何使用上面定义的自定义函数SpatialUnion
Example:用在Select语句中
SELECTSpatialUnion(geometry)
FROMcounties
GROUPBYstate
Example:用在Having语句中,
SELECTgroupcol,MyUDAG(col)
FROMtab
GROUPBYgroupcol
HAVINGMyUDAG(col)>100
ORDERBYMyUDAG(col);
Example:其他
SELECT...,MyUDAG(col)
FROMtab
GROUPBYROLLUP(gcol1,gcol2)
自定义聚集函数可以跟All,Distinct一起使用,亦可以用在Groupby的扩展语句中,像ROLLUP,CUBE,groupingsets.
4.EvaluatingUser-DefinedAggregatesinParallel
跟内置的聚集函数一样,自定义的聚集函数也可以并行来处理,如下图
需要注意的是,自定义的聚集函数需要声明为parallel-enabled,如下
CREATEFUNCTIONMyUDAG(...)RETURN...
PARALLEL_ENABLEAGGREGATEUSINGMyAggrRoutines;
5.User-DefinedAggregatesandAnalyticFunctions
自定义的聚集函数可以被当做Analytic函数来用,
SELECTAccount_number,Trans_date,Trans_amount,
MyAVG(Trans_amount)OVER
PARTITIONBYAccount_numberORDERBYTrans_date
RANGEINTERVAL'7'DAYPRECEDING)ASmavg_7day
FROMLedger;
6.ReusingtheAggregationContextforAnalyticFunctions
当一个自定义的聚集函数被用来做AnalyticFunction的时候,对每条记录对应的window都会计算一次aggregate。一般的说来,每个连续的窗口包含大部分相同的数据集合。
可以通过实现ODCIAggregateDelete接口函数来让Oracle更有效地复用aggregationcontext.
7.AncompleteexampleforCreatingandUsingaUser-DefinedAggregateFunction
SecondMax()返回一组数里面第二大的那个值。
(1)实现类型SecondMaxImpl,该类型包含了ODCIAggregate接口函数,
createtypeSecondMaxImplasobject
(
maxNUMBER,--highestvalueseensofar
secmaxNUMBER,--secondhighestvalueseensofar
staticfunctionODCIAggregateInitialize(sctxINOUTSecondMaxImpl)
returnnumber,
memberfunctionODCIAggregateIterate(selfINOUTSecondMaxImpl,
valueINnumber)returnnumber,
memberfunctionODCIAggregateTerminate(selfINSecondMaxImpl,
returnValueOUTnumber,flagsINnumber)returnnumber,
memberfunctionODCIAggregateMerge(selfINOUTSecondMaxImpl,
ctx2INSecondMaxImpl)returnnumber
);
/
(2).实现类型SecondMaxImpl的body,
createorreplacetypebodySecondMaxImplis
staticfunctionODCIAggregateInitialize(sctxINOUTSecondMaxImpl)
returnnumberis
begin
sctx:=SecondMaxImpl(0,0);
returnODCIConst.Success;
end;
memberfunctionODCIAggregateIterate(selfINOUTSecondMaxImpl,valueINnumber)returnnumberis
begin
ifvalue>self.maxthen
self.secmax:=self.max;
self.max:=value;
elsifvalue>self.secmaxthen
self.secmax:=value;
endif;
returnODCIConst.Success;
end;
memberfunctionODCIAggregateTerminate(selfINSecondMaxImpl,
returnValueOUTnumber,flagsINnumber)returnnumberis
begin
returnValue:=self.secmax;
returnODCIConst.Success;
end;
memberfunctionODCIAggregateMerge(selfINOUTSecondMaxImpl,ctx2INSecondMaxImpl)returnnumberis
begin
ifctx2.max>self.maxthen
ifctx2.secmax>self.secmaxthen
self.secmax:=ctx2.secmax;
else
self.secmax:=self.max;
endif;
self.max:=ctx2.max;
elsifctx2.max>self.secmaxthen
self.secmax:=ctx2.max;
endif;
returnODCIConst.Success;
end;
end;
/
(3).创建自定义聚集函数SecondMax()
CREATEFUNCTIONSecondMax(inputNUMBER)RETURNNUMBER
PARALLEL_ENABLEAGGREGATEUSINGSecondMaxImpl;
(4).使用自定义聚集函数SecondMax()
SELECTSecondMax(salary),department_id
FROMemployees
GROUPBYdepartment_id
HAVINGSecondMax(salary)>9000;
相关文章推荐
- Unsupported Oracle data type USERDEFINED encountered 的一种解决方案
- ORACLE中的自定义聚合函数(User-Defined Aggregate Functions)
- rattle: Graphical user interface for data mining in R
- 遇到不支持的Oracle数据类型USERDEFINED
- User Defined Functions
- Transact SQL User-Defined Functions in SQL Server 2005
- How to set user-defined-type as Oracle SP input parameter in .NET
- 《iOS Human Interface Guidelines》——Accessing User Data
- 自定义函数。用户自定义函数(User Defined Functions)SQL Server 2000
- 102.You want to import schema objects of the HR user using Oracle Data Pump from the development dat
- Part 15 Scalar user defined functions in sql server
- C# 获取ORACLE SYS.XMLTYPE "遇到不支持的 Oracle 数据类型 USERDEFINED"
- Pushing the Limits of User-Defined Runtime Attributes in Interface Builder
- Invoking CLR User-Defined Aggregate Functions
- ABAP开发基础知识:3) 自定义数据类型(User-Defined Data Types)
- Do SQL Server User Defined Datatypes (UDT) affect performance?
- Stored Procedures, Triggers And User Defined Functions on DB2 Universal Database for Iseries
- VHDL之User-defined data types
- WJ的Direct3D简明教程3:Create Texture with User-defined Image Data