PL/SQL架构

PL/SQL的编码和运行时系统是一项技术,而不是一个独立的产品。可以把这项技术想象成一个能够编译并运行PL/SQL块和子程序的引擎。这个引擎可以安装在Oracle服务器上或安装在Oracle FormsOracle Reports这样的开发工具中。所以,PL/SQL可以在两种环境中存在:

  1. Oracle数据库服务器
  2. Oracle开发工具

这两种环境是独立的。PL/SQL虽被绑定到Oracle服务器上,但在某些工具中是无法使用的。在这两种环境下,PL/SQL引擎都能接受有效的 PL/SQL块或子程序。下图是PL/SQL引擎处理匿名块的过程,引擎会处理过程化语句,而把SQL语句发送给Oracle服务器端的SQL语句执行程序(SQL Statement Executor)来处理。

1Oracle数据库中

缺乏本地PL/SQL引擎的应用开发工具就必须依赖于Oracle来处理PL/SQL块和子程序。Oracle服务器除了能够处理SQL语句外,还会处理PL/SQL块和子程序,它会将块与子程序传给它本地的PL/SQL引擎。

  • 匿名块

匿名PL/SQL块能被嵌到Oracle预编译程序(Oracle Precompiler)或是OCI程序中。运行的时候,不含PL/SQL引擎的程序会把这些块发送到Oracle服务器编译并执行。

  • 存储过程

子程序可以独立编译并存储在Oracle数据库。使用CREATE语句显式创建的子程序就是一个"存储"子程序。一旦编译并保存到数据词典中,它就成了一个模式对象(schema object),可以被许多连到数据库的应用程序调用。

定义在包内的存储子程序称为打包子程序(packaged subprogram);单独定义的存储子程序称为独立子程序(standalone subprogram);而在另外一个子程序或PL/SQL块内定义的存储子程序称为本地子程序,这样的子程序不能被其他应用程序调用,只供本地使用。

存储过程执行效率高,耗内存少,应用集成,安全性好。例如,我们设计出一套存储过程和函数时,应用程序就可以调用这些函数和方法,这样就能避免大量的冗余代码提高效能。

我们可以从数据库触发器、其他存储子程序、Oracle预编译程序、OCI程序或是SQL*Plus等,调用存储子程序。例如,我们可以像下面这样从SQL*Plus中调用独立子程序create_dept

SQL> CALL create_dept('FINANCE''NEW YORK');

子程序以分析、编译过的形式保存在数据库中。所以,在被调用时,它们会被立即加载并传递到PL/SQL引擎。并且,它们还会利用共享内存,这样,每次只要有一个子程序需要被加载到内存,就能被多个用户调用执行。

  • 数据库触发器

数据库触发器是与数据库中某个数据表、视图或事件相关联的存储子程序。举一个例子,我们可以让Oracle数据库在INSERTUPDATE DELETE表达式影响一个表之前或之后来自动激活一个触发器。触发器的用途之一就是审核数据修改。例如,下面的表级(table-level)触发器会在emp表的salaries字段更新后被激活。

CREATE TRIGGER audit_sal
  AFTER 
UPDATE OF sal
  
ON emp
  
FOR EACH ROW
BEGIN
  
INSERT INTO emp_audit
       
VALUES ...
END;

触发器执行部分可以包括过程语句和SQL数据操作语句。除了表级触发器以外,还包含替代触发器(instead-of triggers for views)和系统触发器(system-event trigger)

2Oracle工具中

在包含PL/SQL引擎的条件下,应用开发工具就能够处理PL/SQL块和子程序。开发工具会把块传给它的本地PL/SQL引擎。引擎会在应用程序段执行所有的过程语句,只把SQL语句发送给Oracle。因此,大多部分工作会在应用程序端完成,而不是在服务器端。进一步说,如果块中不包含任何 SQL语句的话,这个引擎会在应用程序端执行全部的代码。

PL/SQL的优势

PL/SQL是一个可移植、高效的事务处理语言:

  1. 支持SQL
  2. 支持面向对象编程
  3. 良好的性能
  4. 效率高
  5. 可移植
  6. Oracle集成
  7. 高度安全

1SQL的支持

SQL因为它的灵活、强大和易学,已经成为标准的数据库语言。只要几个像SELECTINSERTUPDATEDELETE这样简单的命令就能轻松地操作关系数据库中的数据。SQL是非过程化的,这就是说我们可以决定做我们想做的,但不能决定如何做。Oracle会决定处理我们请求的最佳方案。

PL/SQL能让我们使用所有的SQL数据操作,游标控制和事务控制命令;也可以使用所有的SQL函数,操作符和伪列。所以,我们可以灵活安全地操作Oracle数据。PL/SQL完全支持SQL数据类型,这就减少了我们的应用程序和数据库间数据传递时的类型转换。

PL/SQL也支持动态SQL语句,这样能够让我们的应用程序更加灵活通用。程序可以在运行时处理SQL数据定义、数据控制和会话控制语句。

2、面向对象的支持

对象类型是理想的面向对象建模工具,它能帮助我们创建复杂的应用程序。除了能创建模块化,易维护和重用性高的软件组件外,对象类型还可以让不同开发组的程序员并发地开发组件。

对象类型通过对数据操作的封装,把数据维护代码从SQL脚本和PL/SQL块中提取出来,放到独立的方法中去。同样,对象类型也可以隐藏实现,这样我们就在不影响客户端程序的情况下改变实现细节。

此外,真实世界的复杂实体和关系也能够映射到对象类型中去。这样我们的程序就能更好将模拟的内容反映出来。

3、良好的性能

如果没有PL/SQL的话,Oracle就必须每次接收一条SQL语句,然后处理。每条SQL语句都会调用一次Oracle,这就造成很大的运行开销。在网络环境中,这种现象就更加明显。如下图所示,如果应用程序与数据库之间交互频繁,那么就可以在向Oracle发送SQL语句之前使用PL/SQL 块和子程序把SQL语句组合起来。

有了PL/SQL,整块的语句就可以一次传递给Oracle,这样就能减少应用程序和Oracle的通信,减少网络开销,如下图所示,如果我们的应用程序与数据库的交互操作较多,那么就可以用PL/SQL块和子程序将SQL语句组织起来一次性地发送给Oracle执行。

PL/SQL块和子程序能够在编译成可执行的形式存放起来,所以调用存储过程是快速和高效的。而且,存储过程是在服务器端执行的,减少网络流量改善响应时间。可执行的代码会被自动地放到缓存然后在多个用户间共享。

我们也可以为Oracle工具提供PL/SQL的过程处理功能来改善性能。这样我们就可以直接利用工具来进行计算而不用调用Oracle服务器。这样会节省大量的时间和网络开销。

4、高效性

对于像Oracle FormsOracle Reports这样的非过程化工具,在加入了PL/SQL功能后,我们也可以使用熟悉的过程语句来建立应用程序。例如,我们可以在Oracle Form触发器中使用整块整块的PL/SQL块,而不必多次调用触发器,宏等。所有环境中的PL/SQL都是一样的。一旦我们掌握了PL/SQL,那么我们就可以在任何支持PL/SQL的工具中使用它。

5、可移植性

PL/SQL编写的应用程序都可移植到Oracle运行的操作系统和平台。换句话说,PL/SQL程序可以在任何Oracle能够运行的地方而运行,因此,我们不必为每一个新环境定制一套新的PL/SQL程序。

6、与SQL紧密结合

PL/SQLSQL语言是紧密结合的。PL/SQL支持所有的SQL数据类型和NULL。这样一来,我们操作Oracle数据就变得方便快捷。% TYPE%ROWTYPE属性进一步的拉近PL/SQLSQL的关系。例如,我们可以通过%TYPE属性,在已定义的数据库字段的基础上声明同类型的变量。如果数据库定义发生改变的话,在下一次编译或运行时,变量的声明类型也会随之变化。这就减少了代码维护的开销,使程序自动地适应于新的业务需求。

7、高度安全

PL/SQL存储过程能使客户端和服务器端的逻辑分离,避免让客户端操作敏感的Oracle数据。用PL/SQL编写的触发器可以有选择性的允许应用程序更新数据,并可以根据已有的内容来审核用户的插入操作。

另外,我们还可以让用户只通过调用定义者权限的存储过程,来严格控制用户对Oracle数据的访问。例如,我们可以授权用户来调用更新数据表的存储过程,但不授权他们直接访问数据表的权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值