分享
 
 
 

用Oracle用户自定义合计函数来提高代码重用性

王朝oracle·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

合计函数(aggregate functions)就是对一组数据行进行处理的函数,如max和min(对一组数据取最大值和最小值)函数,合计函数用来简化开发者执行某个任务的逻辑复杂度。从Oracle 9i开始,开发者可以创建用户自定义的合计函数,它们可以重复使用而无需做任何修改。 通过强有力的编程构造,合计函数实际上很轻易编写。现在让我们看看它是如何工作的。

创建toList

为了看看构造合计函数是多么的简单,我举了一个合计函数的例子,即toList函数。该函数的参数为一组记录,它的功能是把保存在这些记录的特定字段的数据组合到一个用逗号做分隔符的清单中(成组)。下面的查询是一个例子供你参考:

select author, toList(title) titles

from books

group by author;

上面代码的运行结果如图A所示。

图A

ToList函数创建了一个书目清单

尽管我是使用Oracle的PL/SQL语言来创建我的toList函数的,你可以使用任何Oralce所支持的语言(如C++或者java)来创建合计函数。所有的代码都可以在SQL*Plus、SQL*SPReadsheet以及其它Oracle SQL应用程序中执行。

创建一个合计函数分为五个步骤:规划函数的逻辑、创建函数的对象类型的对象头(object header)、编写对象类型的代码、例化对象类型、最后测试该函数。我将按顺序向你介绍这些步骤。

规划逻辑

我喜欢正式规划我所写的程序,所以我为toList函数编写了伪代码,如清单A 所示,这些伪代码就是我的逻辑规划。Oracle实际上为我处理了该过程的相当多的部分,也就是说我实际上需要写的代码只包括下面三个部分:公布list变量、添加逗号的if语句以及组成返回值的字段名。

创建对象头(object header)

对象头定义为持久变量以及对该对象成员函数的说明。所有的对象必须包含ODCIAggregateInitialize、ODCIAggregateIterate、ODCIAggregateMerge和ODCIAggregateTerminate这四个函数,称之为强制函数(mandatory function),为了易读起见,我在后面将这四个函数分别简称为Initialize,、Iterate、Terminate和Merge函数。在后面介绍这四个函数各自的代码时,我再解释它们的功能。 代码清单B 为toList的对象头。

在清单B中,toListImpI是对象类型的名字,而list是我所定义的唯一的持久变量。

编写成员函数的代码

一旦创建好对象头,你就应该编写函数的代码。 代码清单C 包括了toList成员函数的函数体代码。尽管这个代码清单有些长,但是大多数都是从一个样板出来的,函数之间的差别不大。

每个函数都返回一个数来表示运行结果是成功与否。ODCIConst.sUCcess表示运行成功。现在你已经看到了这些函数的代码,那么四个强制函数中的三个的功能应该很轻易理解了:

Initialize函数对数据组各个需要处理的字段各运行一次。自然的,我需要为每一个值预备一个新的清单,所以需要初始化持久变量list,这里初始化值为null。

Iterate函数处理返回的行,所以实际上是由它来创建返回的值的清单。先测试list是否为空,假如为空,就把list直接设置为所引入的value值;假如list变量非空,则给list添加一个逗号后再插入value值。

Terminate函数在数据组的每个行的感爱好字段数据被处理后执行。在这个函数中我只需简单的返回清单变量即可。

第四个函数,即Merge函数,仅仅是用来返回成功标记的。

创建该合计函数

一旦你写完所有的这些代码,剩下的唯一事情就是通过运行下面的指令来创建该合计函数(这用到你刚刚创建的toListImp1类型):

create or replace function toList (input STRING) return STRING

aggregate USING toListImp1;

现在开始进入最有趣的工作环节:测试。你可以用 清单D 中的代码创建一个简单的书目表并载入一些数据进行测试。

使函数具有并行处理能力

合计函数的另一个优点就是你可以让它们具有Oracle的并行处理特性。为了让你的合计函数具有并行处理能力,你需要编写Merge函数的代码并需要对合计函数的脚本略做修改。注重我已经给你的代码是正确完整的、并带有并行处理选项。

当一个合计函数在多个处理器上运行时,Oracle 9i服务器可以在两个或者多个处理器上运行Iterate函数。每个处理器返回一部分结果,Merge函数把这些离散的结果合并到一个变量。Oracle 9i服务器将反复调用Merge函数直到所有的部分结果合并完毕为止。

为了让toList函数可以并行处理,你首先需要Merge函数的代码,你可以在清单E中找到它的代码。

我还需要在创建该合计函数时公布它具有并行处理的能力:

create or replace function toList (input STRING) return STRING

parallel_enableaggregate USING toListImp1;

现在,toList函数已经充分利用了多处理器的优点了。

使用技巧

假如你不想按字段成组,那么可以按常量进行,例如:

Select toList(distinct Author) authors From books Group by ‘1’

你也许希望增强你的合计函数的健壮性,就像在其它程序中所作的那样。例如,在我的Merge函数中,也许应该检测合并的两个内容是否超过了list的最大答应字符数(32767)。

假如你的Oracle服务器没有配置成支持并行处理的方式,我建议你仍在你的合计函数中考虑添加并行支持功能。因为这只需花费一点点附加时间,但是这就增加了你的函数在其它处理环境中的可移植性和可重用性。

最后你还需要注重,Oracle 9i将会答应你创建一些根本就不能运行的合计函数。例如,尽管Oracle答应你创建参数超过一个的合计函数(也就是说,该合计函数将使用多个函数),但是使用该合计函数将会发生错误。同样的,尽管你可以重载合计函数,但是当你尝试使用它们的时候却会导致失败。

创建自己的合计函数是扩展Oracle统计和文本处理例程(Oracle本身并没有内建这个功能)的重要途径。使用这个技术的地方几乎数不胜数,所以你需要把握这个技术。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有