《Oracle PL/SQL程序设计(第5版)》一一1.4 关于PL/SQL的版本

本节书摘来自异步社区出版社《Oracle PL/SQL程序设计(第5版)》一书中的第1章,第1.4节,作者:【美】Steven Feuerstein , Bill Pribyl,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 关于PL/SQL的版本

Oracle PL/SQL程序设计(第5版)
每个版本的Oracle数据库都有其对应的PL/SQL版本。只要我们使用的是最新版的PL/SQL,就会有更多的功能供我们使用。作为PL/SQL程序员的最大挑战就是“紧跟”。我们不需要不断地自学每个版本中的新特性─学会使用它们,尤其在我们自己的应用程序中该如何使用,确定有些新技术尤其有用,我们应该利用这些新技术修改已有的应用程序。

表1-1总结了数据库中每一版(过去的和当前的)PL/SQL的主要成员(注意在早期的数据库版本中,PL/SQL的版本号和数据库的发布号不一样,不过从Oracle 8开始,二者就统一了)。在这个表中高度概括了每个版本的新特性。在后面的内容中,我们会给出目前最新版的Oracle数据库11g中的PL/SQL“新特性”的详细描述。

Oracle Developer 产品套件也有它自己的 PL/SQL 版本,通常要落后于Oracle 数据库本身的版本。这一章(这个这本书)关注的是服务器端的PL/SQL编程。
image
image

1.4.1 Oracle数据库11g的新特性

Oracle数据库11g提供了许多新特性,用于改性PL/SQL的性能和可用性。它也修复了语言的某些“未尽之处”。下面总结了对于PL/SQL开发人员来说最重要的变化(除非另有注明,所有的特性都是R1和R2版本都有的)。

基于版本的重定义功能(只有R2版本才有)
从历史上看,如果应用程序是基于Oracle数据库构建的,那么当对数据库对象打补丁或者升级时,这个应用程序必须要下线。Oracle数据库11g R2版本引入了一个革命性的新功能功能,可以在不打断应用程序运行的前提下在线对应用程序进行升级。现有的会话可以继续使用升级前的应用程序,知道这些程序的用户确定了结束;然后,同一时刻,新的会话就可以使用升级后的应用程序了。当没有会话再使用升级前的应用程序时,它就可以退役了。于是,应用程序作为一个整体可以从升级前版本热过度到升级后的版本。

这个新功能用到了许多的数据库特性,不过最主要的还是基于版本的重定义。尽管应用程序架构要负责大部分的基于版本的重定义任务,不过对于开发人员来说这个功能也是非常有趣的。

基于版本的重定义功能在第20章介绍。

CREATE TYPE的FORCE选项(只有R2版本才有)
现在我们可以通过“CREATE OR REPLACE”指明我们要强制创建一个新类型,就算来由其他类型依赖它。在以前的版本中,这种操作尝试会抛出ORA-02303异常。

第26章有关于RCE选项的更多内容。

函数结果缓存
在Oracle数据库11g之前的版本中,对于PL/SQL程序缓存数据而言,最好、最灵活的方法就是基于包的缓存。可悲的是,这种方法适用的场景很有限,因为数据源必须要是静态的,而且随着会话连接到Oracle数据库,内存消耗也会增长。

认识到这种缓存方法带来的性能好处,Oracle在Oracle数据库11g R1版本实现了函数结果缓存,并在R2版本加强。这个功能提供的缓存解决方法克服了基于包的缓存的一些不足,而性能差不多同样得快。当我们为某个函数打开函数结果缓存时,我们可以得到下面这些好处。

Oracle数据库用一个单独的缓存区为每一个函数同时保存输入和返回值。这个缓存区被连接到这个数据库实例的全部会话共享,而不是为每一个会话复制。
每当函数被调用时,数据库就会检查是否已经缓存了相同的输入值。如果是,则函数就不用执行了。把缓存中的值简单返回就可以了。
每当发现要修改的是缓存所依赖的表时,数据库会自动的把缓存无效。后续的函数调用会用一致数据重新填充缓存。
我们一定要找机会试试这个突出的特性,第21章会更详细的介绍。

CONTINUE语句
Oracle数据库11g为循环提供了一个新特性:CONTINUE语句。用这个语句可以退出循环的当前迭代,继续循环的下一次迭代。这个语句有两种形式,就像EXIT:无条件的CONTINUE以及有条件的CONTINUE WHEN。

下面是一个使用CONTINUE WHEN的简单例子,这个例子在遇到偶数时跳过循环体的执行:

BEGIN
  FOR l_index IN 1 .. 10
  LOOP
   CONTINUE WHEN MOD (l_index, 2) = 0;
   DBMS_OUTPUT.PUT_LINE ('Loop index = ' || TO_CHAR (l_index));
  END LOOP;
END;

CONTINUE语句会在第5章详细介绍。

PL/SQL表达式中的序列
现在我们可以在PL/SQL中直接使用sequence_name.CURRVAL和sequence_name.NEXTVAL,不再需要SELECT FROM SYS.dual了。

在第14章中会有更多的细节。

动态SQL的增强
PL/SQL的开发团队已经大大地增强了两类动态SQL(DBMS_SQL和原生动态SQL)之间的互操作性,以及功能覆盖的完整性的改进。比如,我们现在可以在一个DBMS_SQL游标数值和游标变量间相互转化。我们也可以EXECUTE IMMETIATE一个CLOB。

Oracle数据库11g还加强了DBMS_SQL的安全性。现在这个包可以防止这种情况:一个程序使用DBMS_SQL并且抛出异常,攻击者就可以利用未关闭的游标危害数据库的安全。对全权的加强包括生成不可预测的(可能是随机的)游标数值,当传给DBMS_SQL的是无效的游标数值时限制DBMS_SQL的使用,如果用户要使用的游标和游标被用户打开时已经不一样了,也会拒绝DBMS_SQL的操作。

有关这些特性的更多内容见第16章。

新的原生编译和SIMPLE数据类型
PL/SQL原生编译器现在可以直接生成原生机器代码,而不是把PL/SQL代码翻译成C代码,然后再由C编译器生成机器代码。使用原生编译现在也很简单:每个开发人员都无需DBA的介入就可以对PL/SQL单元进行原生编译。我们可以期望原生编译代码的执行速度会有大幅提升,也许是一个数量级提升。而且如果打开原生编译,我们可以从某些新的、专门的数值类型中获得性能提升:SIMPLE_INTEGER、SIMPLE_FLOAT和SIMPLE_DOUBLE。

第24章会介绍原生编译,第9章介绍这些新的数值类型。

SecureFiles
有关LOB实现方式的术语在Oracle数据库11g已经变了。Oracle用一个叫做SecureFiles的技术重新实现了LOG。SecureFiles对LOG管理的很多方面都做了改进,包括磁盘格式,缓存,锁,重做日志,以及空间管理算法。这种更新的技术显著的改善了LOG的性能,还可以通过简单的参数设置实现LOG的复制、压缩、以及加密。

有关使用SecureFiles的更多内容,见第13章和23章。

触发器的增强
我们现在可以创建复合触发器,可以把以前是分开的触发器(事件的BEFORE和AFTER触发器)合并到一个代码体中,这个代码体中有不同的事件单元。这种触发器会让维护复杂的触发器逻辑变得更简单,尤其是对突变表触发器错误。如果同一个事件(以及同一个数据库对象)上定义了多个触发器,现在我们也可以定义这些触发器的执行顺序了。

符合触发器在第19章详细介绍。

自动的子程序插入
一个新的编译器优化级别(级别3)实现了自动的子程序插入,也就是说编译器把一个局部子程序调用(在同一个PL/SQL单元声明的子程序)用子程序的实现代码拷贝替换。这个优化可以减少运行时的代码执行量因为不再需要“查找动作”发现子程序并执行。

第21章介绍了优化级别及PL/SQL性能的其他方面内容。

PL/Scope
PL/Scope是一个编译器驱动的工具,可以从PL/SQL源代码中收集整理有关用户自定义标识符的数据,并让这些数据可以通过ALL_IDENTIFIED数据字典视图使用。PL/Scope使得为我们的应用程序构建一个自动的、复杂的质量保证的程序非常容易。我们会非常喜欢在使用的PL/SQL编辑器中使用PL/Scope,不过我们也可以基于ALL_IDENTIFIERS编写一些查询(有点复杂)来“挖掘”我们的代码。

第20章有PL/Scope更详细的说明。

PL/SQL层次化分析器
在Oracle数据11g中,Oracle用一个新的层次化分析器完善现有的PL/SQL分析器(DBMS_PROFILER)。通过使用提供的DBMS_HPROF包,我们可以获得按照子程序调用进行组织的PL/SQL代码动态运行的分析信息。这个分析器把SQL和PL/SQL的执行次数分开统计。每个子程序级别的统计都包括关键数据、子程序的调用次数、子程序花费的时间以及这个子程序的子树(它又调用的子程序)花费的时间,以及详细的父子信息。

第21章会讨论传统的分析器和层次化的分析器。

细粒度依赖关系跟踪
在Oracle数据库11g之前,对依赖关系的记录粒度是把整个对象作为一个整体看待。如果对象有了任何改动,所有依赖程序单元都会被标志成无效,即使这个修改根本没有影响这个程序单元。在Oracle数据库11g中,Oracle把依赖关系的跟踪微调到对象内的元素级别。比如,对于表来说,Oracle数据库现在记录的是某个程序单元依赖表中的某些列。利用细粒度的依赖关系跟踪,数据库可以避免某些之前版本数据库需要的重新编译,从而使得应用程序代码升级更加容易。

第20章会讨论更多有关细粒度依赖关系跟踪的内容。

在子类中调用超类
Oracle面向对象功能中的一个限制在Oracle数据库11g得到了改进,也就是在当前(或者高级别的)子类中可以调用超类中一个已经被重载的方法。在Oracle数据库11g之前,如果在子类中重载了超类的一个方法,我们就无法再在子类的一个实例中调用超类的方法。现在可以了。在Oracle的超类调用实现方式中,我们不需要用SUPERTYPE关键字引用超类,就像其他的面向对象语言那样。相反,我们必须制定类层次结构中的特定超类。这种方法更加灵活些(我们可以随意调用任何一个超类的方法,不过这也意味着我们必须在子类的代码中硬编码超类的名字)。

第26章有关于这个特性的进一步讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值