网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > 数据库技术 > Oracle > PL/SQL > PL/SQL 集合相关功能探讨  

PL/SQL 集合相关功能探讨

2004-10-21  作者:BitsCN整理  来源:中国网管联盟  点评 投稿 收藏


  Oracle PL/SQL变得更快、更易于使用,特性集也更加丰富了。Oracle数据库10g通过一系列有益的改进,继续保持了PL/SQL在速度、简单易用性和特性扩展方面的传统优势,这些改进包括:
  
  大大提高了执行速度,这要归功于透明的性能改进,其中包括一个新的优化编译器、更优的集成化本地编译功能,以及帮助解决数字运算应用程序问题的新的数据类型。
  
  FORALL语句更加灵活、更加有用。例如:FORALL现在支持非连续索引。
  
  正则表达式以三个新函数(REGEXP_INSTR、REGEXP_REPLACE和REGEXP_SUBSTR)和用于比较的REGEXP_LIKE运算符的形式用于PL/SQL语言中。(要获得更多信息,参见本期杂志中Jonathan Gennick撰写的《一流的表达式》一文。)
  
  集合得到了改进,包括比较集合是否相同、支持对嵌套表进行集合运算等。
  Oracle数据库10g使PL/SQL继续保持其作为Oracle数据库的最高效、最富生产力的编程语言的地位。其在性能方面的大大提升,以及对IEEE算法和正则表达式的支持,如今完全开启了将PL/SQL作为首选语言的新的功能领域。 网管朋友网www_bitscn_net
  
  作为介绍Oracle数据库10g中的PL/SQL系列文章的第一篇,本文将对Oracle数据库10g中与集合相关的一些改进进行探讨。
  
  比较集合
  20世纪90年代末期,当我首次对开发人员进行PL/SQL培训的时候,很少有人使用(甚至知道)包(package),而现在,很多人(包括我自己在内)都认为它是任何设计精良的PL/SQL应用程序的基础。如今,打包软件得到了广泛使用。 目前,非常重要但未得到充分利用的PL/SQL特性的前沿领域似乎就是集合的使用了。
  
  集合是Oracle中的数组,集合是一维列表。早在Oracle7中,就已经用到了集合(那时,称作“PL/SQL表”),但其功能及性能却很有限。不过,Oracle后来的各个版本都对集合进行了改进。在Oracle数据库10g中,这些数据结构对于几乎所有的复杂PL/SQL应用程序项目来说都是强有力的、快速的和必不可少的。
  
  Oracle数据库10g对集合的一个关键性改进是能够比较两个集合内容的相同之处(和不同之处)。在Oracle数据库10g之前,你也可以对两个集合进行比较,但必须为此编写一个函数。编写这样的程序时需要考虑数个复杂因素,包括:

网管bitscn_com


  
  必须为正在使用的各个集合类型分别编写程序。即使两个集合中的数据类型相同,但如果它们不是基于完全相同的类型定义的,你都需要使用不同的函数来进行比较。
  
  必须对表的内容进行逐行比较,这就意味着必须进行“全集合扫描”。完成这一任务的代码不是很复杂。但是,这一代码冗长乏味,易于出错,特别是比较诸如记录、对象或者XMLType等复杂数据类型的集合时更是如此。
  
  你必须决定如何处理NULL。如果两行都包含NULL,那么它们相同吗?Oracle认为:“它们既不是相同,也不是不相同,”但是,你的判断可能会与此不同,你必须编写代码来处理这个问题。
  这种复杂性导致你不愿意经常编写这类程序,你甚至会在应用程序中回避编写这类程序。
  
  在Oracle数据库10g中,collcompare.sql文件包含了这类程序的一个示例,该程序是为基于employee表的记录集合而编写的。
  
  假设我在collcompare.sql脚本中安装了emp_coll_pkg.equal函数。我可以按照如下方式来使用它:
  
  DECLARE
  dbas emp_coll_pkg.employee_tt;
  developers emp_coll_pkg.employee_tt; 网管有家www.bitscn.net
  
  BEGIN
  populate_lists (dbas, developers);
  
  IF emp_coll_pkg.equal (dbas, developers)
  THEN
  DBMS_OUTPUT.PUT_LINE (
  'Likely a very small IT organization!');
  END IF;
  END;
  
  这段代码简单明了、可读性好。(你不用再经历编写此类函数的痛苦过程多好啊!)为了让你工作更轻松,Oracle数据库10g现在允许你对两个嵌套表进行“原始”比较(native compare)了。换句话说,你不必再编写任何特定于集合的比较逻辑,而可以直接进行比较,如下所示:
  
  DECLARE
  dbas emp_coll_pkg.employee_tt;
  developers emp_coll_pkg.employee_tt;
  BEGIN
  populate_lists (dbas, developers);
  
  IF dbas = developers
  THEN
  DBMS_OUTPUT.PUT_LINE (
  'Likely a very small IT organization!');
  
  END IF;
  END;
  
  在这种情况下,集合比较仅适用于嵌套表。换句话说,你还不能直接比较两个关联数组(过去称作\"索引表\")或者变长数组的内容。希望Oracle数据库的下一版本会增加关联数组和变长数组的比较功能。
网管下载dl.bitscn.com

  
  集合理论与Multiset Union运算
  SQL语言很久以前就提供了将集合运算(UNION、INTERSECT和MINUS)用于查询结果集的功能。如今在Oracle数据库10g中,你可以对PL/SQL程序中的嵌套表(且仅限于嵌套表)和在关系表中声明为列的嵌套表使用上述功能强大的高级运算符。
  
  现在我们从UNION开始,看看这样做所需的一些语法。
  
  首先,我创建一个模式级别的嵌套表类型:
  
  CREATE OR REPLACE TYPE strings_nt
  
  IS TABLE OF VARCHAR2(100);
  /
  
  然后,我定义一个包,在该包中,我创建并填充两个此种类型的嵌套表,每个嵌套表都包含一些我和我父亲最喜欢的东西:
  
  CREATE OR REPLACE PACKAGE favorites_pkg
  IS
  my_favorites  strings_nt
  := strings_nt ('CHOCOLATE'
  , 'BRUSSEL SPROUTS'
  , 'SPIDER ROLL'
  );
  
  dad_favorites  strings_nt
  := strings_nt ('PICKLED HERRING
  , 'POTATOES'
  , 'PASTRAMI'
  , 'CHOCOLATE'
  );
  PROCEDURE show_favorites (
网管论坛bbs_bitsCN_com

  title_in  IN  VARCHAR2
  , favs_in  IN  strings_nt
  );
  END;
  /
  
  在该包中,我还创建了一个用于显示strings_nt 嵌套表内容的过程。下面很快就会用到它。
  
  通过在任意程序外的包中定义这些集合,这些集合在我的对话期间会一直保持不变(保持其状态和值),直到我将更改或删除它们为止。这就是说,现在我可以在包外编写程序来对这些集合的内容进行操作了。
  
  注意,出于介绍集合功能的目的,我对该包进行了简化。在生产应用程序中,你应该时刻注意“隐藏”包主体中的包数据(如同这些集合一样),然后提供过程和函数来管理这些数据。
  
  例如,假设我想把这两个集合合并成一个“我们的最爱”的集合。在Oracle数据库10g出现以前,我必须编写一个将一个集合的内容转移到另一个集合的循环。而现在,我可以依赖MULTISET UNION运算符来实现这一点了,如下所示:
  
  DECLARE
  our_favorites
  strings_nt := strings_nt ();
  BEGIN
  our_favorites :=
  favorites_pkg.my_favorites
  MULTISET UNION
  favorites_pkg.dad_favorites;
网管bitscn_com

  
  favorites_pkg.show_favorites (
  'ME then DAD', our_favorites);
  
  END;
  /
  
  此脚本的输出结果为:
  
  ME then DAD
  1 = CHOCOLATE
  2 = BRUSSEL SPROUTS
  3 = SPIDER ROLL
  4 = PICKLED HERRING
  5 = POTATOES
  6 = PASTRAMI
  7 = CHOCOLATE
  
  可以看出,两个嵌套表的值被合并到一起了。而且立刻就可以看到,MULTISET UNION运算符不同于SQL UNION运算符(实际上,与SQL的UNION ALL运算符完全相同)。对两个SELECT结果集进行UNION运算时,SQL引擎会自动生成一个惟一的有序结果集。换句话说,如果我的两个嵌套表都是查询,那么UNION将生成这样的结果集:
  
  BRUSSEL SPROUTS
  CHOCOLATE
  PASTRAMI
  PICKLED HERRING
  POTATOES
  SPIDER ROLL
  
  这些数据是按照字母顺序排列的,且CHOCOLATE仅出现一次。为什么会产生不同的结果呢?因为嵌套表是一种多集合(multiset),mathworld.wolfram.com/Multiset.html 对其做了如下定义:
  
  “一种类似于集合的对象,在其内部,顺序没有意义,而多重性却具有明确的意义;因此,多集合{1, 2, 3}和{2, 1, 3}是等同的,而{1, 1, 2, 3}和{1, 2, 3}却是不同的。” 网管联盟bitsCN_com
  
  Oracle文件中说,嵌套表和变长数组的区别在于嵌套表列中存储的数据不保存其顺序,而在变长数组中存储的数据保存其顺序。在Oracle数据库10g之前,这种区别在PL/SQL中没多大意义。现在,有了集合运算符之后,多集合(或嵌套表)的特性便显得极为重要了。
  
  为了更好地理解嵌套表数据没有顺序,MULTISET UNION也不会对结果嵌套表应用顺序这一特性,请我们来看看面的这个程序块:
  
  DECLARE
  our_favorites
  strings_nt := strings_nt ();
  BEGIN
  our_favorites :=
  favorites_pkg.dad_favorites
  MULTISET UNION
  favorites_pkg.my_favorites;
  favorites_pkg.show_favorites (
  'DAD then ME', our_favorites);
  END;
  /
  
  与前面的程序块惟一不同的是,我改变了MULTISET UNION运算中嵌套表的顺序。结果就变为:
  
  DAD then ME
  1 = PICKLED HERRING
  2 = POTATOES
  
  3 = PASTRAMI
  4 = CHOCOLATE
  5 = CHOCOLATE
  6 = BRUSSEL SPROUTS
网管网www_bitscn_com

  7 = SPIDER ROLL
  
  如果你不希望合并之后的嵌套表中出现重复项,那么可
TAGs探讨   功能   相关   集合   Oracle   比较   数据库   运算   PL/SQL    
 上一篇:使用Text_IO实现EXCEL报表的PLL程序包   下一篇:Oracle应遵循的PL/SQL编码规则
相关文章列表
PL/SQL 集合相关功能探讨 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
1.PL/SQL - 嵌套游标 cursor-PLSQL
2.用一个实例讲解Oracle数据库的PL/SQL语句
3.PL/SQL----触发器-PLSQL
4.mysql存储过程写法—动态参数运用-PLSQL
5.PL/SQL Developer导出分区索引脚本-PLSQL
6.PL/SQL collection— table() 函数-PLSQL
7.SQL Server 2005 中的架构与用户-PLSQL
8.Oracle数据库维护常用SQL语句集合(2)-P
9.Oracle数据库维护常用SQL语句集合(3)-P
10.再议SQL Server临时表和表变量-PLSQL
最新推荐文章:
1.与数据库无关的处理放到数据库以外来实现
2.Oracle 10g第2版新特性之SQL和PL/SQL
3.通过PL/SQL访问Web Services
4.菜鸟学oracle - 用PL/SQL画直方图
5.重新编译PLSQL中无效对象或指定对象
6.Oracle高级技巧
7.深入了解Oracle 10g新的多重集运算符
8.在SQL中删除重复记录(多种方法)
9.Oracle:PL/SQL中怎样使用Array
10.数据库手册:速查Oracle函数列表
网管论坛交流:
·大家来开心一下吧---看了会很开心的东西-
·中国人不可不知道的知识
·@@小鹏◎◎小鹏同志与某位女明星亲密接触
·◎◎小鹏◎◎发现不明生物,居然正在交配
·[图文]^^^版主是什么?????
·泡论坛的女人是好女人
·做个“水性杨花”的女人
·献给mm俱乐部的所有mm
·深圳一集团企业电脑基础应用培训教程
·■■■■十一遊玩照■■■■■