一、过程与函数区别
1.过程可以有0~N个返回参数,通过OUT or IN OUT参数返回;函数有且仅有1个返回值,通过return语句返回。
2.调用过程时,可做为单独的语句执行;调用函数时,函数必须把返回结果赋值给一个变量。
3.在SQL语句中,可以不能调用过程;在SQL语句中,可以直接调用函数。
二、过程与函数
过程[procedure]及函数[function]这两种方案对象均由 SQL 语句及 PL/SQL 语言构件组合而成,存储于数据库中,运行时作为一个整体,用于解决某个问题,或完成一组相关的操作。调用者可以在调用过程及函数时为其提供参数,参数可以专用于输入值,专用于输出值,或同时用于输入及输出值。在过程与函数中,用户既可以发挥 SQL 的灵活性与易用性,也能够发挥结构化编成语言的过程控制能力。过程与函数基本类似,唯一区别在于函数总会向调用者返回一个值,而过程无此特性。
三、存储过程在以下方面具有优势:
1.利用定义者权限过程[definer's rights procedure]确保数据安全
使用存储过程有助于确保数据安全。具备数据库对象访问权限的用户可以定义存储过程或函数,其他用户通过已定义的过程访问数据,从而达到限制用户对数据库操作的目的。
例如,现有一个过程能够更新某数据表,管理员不必授予用户直接访问数据表的权限,而是授予用户访问此过程的权限。当用户调用此过程时,过程以其拥有者的权限运行。具备执行此过程权限(但不具备查询,更新,及删除底层表数据权限)的用户可以调用过程对表进行操作,但不能以其他方式操作表数据。
2.通过调用者权限过程[invoker's rights procedure]使用调用者的权限及方案上下文
调用者权限过程可以继承其调用者的权限及方案上下文。即调用者权限过程不与特定的用户或方案绑定,每次执行时利用当前用户的权限操作当前用户的方案对象。应用程序开发者可以通过调用者权限过程使应用逻辑集中化,即便底层数据分散于不同的用户方案中。
例如,以经理身份登录的用户运行针对 employees 表的更新过程时可以修改薪水数据,而以职员身份登录的用户运行同样的的更新过程时只能修改地址数据。
3.提升性能
- 与向 Oracle 提交 SQL 语句或 PL/SQL 块代码相比,使用存储过程时通过网络传输的数据量较小,因为存储过程只有在定义时需要被传输到服务器,而使用时只需进行调用。
- 数据库以编译后的形式保存过程,因此执行期间无需进行编译。
- 如果过程已经被加载到系统全局区[system global area,SGA]的共享池[shared pool]内,则过程可以直接执行,而不必从磁盘获取。
4.内存分配
存储过程可以利用 Oracle 的共享内存特性,多个用户执行同一个过程时只需将一份过程副本加载到内存中。通过在多个用户间共享相同的代码,能够显著地减少应用程序所需的 Oracle 内存。
5.提高开发生产率
利用存储过程能够提高开发生产率。在一组公用的存储过程的基础上开发应用程序,能够避免冗余代码从而提高开发生产率。
例如,开发者可以编写存储过程,分别对 employees 表内的员工数据进行插入,更新及删除操作。任何应用程序都可以调用这些过程,而无需重写 SQL 语句就可以完成相应的工作。如果数据管理的方式发生变化,只需修改存储过程,而不必修改调用过程的应用程序。
6.完整性
存储过程能够提高应用程序所处理数据时的一致性与完整性。由于应用程序是在一组 公用存储过程的基础上开发的,因此能够减少提交代码发生错误的可能性。
例如,用户可以对过程或函数进行测试,确保其返回准确的结果,一旦验证则可以在其他应用程序中重复使用而无需再次测试。如果过程所引用的数据结构发生变化,只需修改存储过程,而不必修改调用过程的应用程序。
四、过程开发指南
以下是设计存储过程时需要遵循的原则:
- 在一个存储过程中应该只实现一个单一的任务。不要定义执行多个子任务的大型存储过程,如果在多个过程中实现了相同的子任务将造成不必要的代码重复。
- 不要定义过程来实现 Oracle 已经提供的功能。例如,不要定义过程来强制实现简单的数据完整性规则,此类功能只需要声明数据完整性约束即可实现。
五、包
包[package]是由一组相关的过程,函数,及其使用的游标,变量等构成的程序单元,存储于数据库中供用户使用。与独立的过程及函数类似,包过程与包函数也可以由应用程序及用户显式地调用。
包在创建时分为两部分:包规范与包体。包规范[package specification]用于声明所有公有程序结构,而包体则用于对所有程序结构进行定义(包括公有及私有)。将包分为两部分具有以下优势:
- 可与使开发周期更灵活。用户可以首先声明包规范而不定义包体,此时已声明的公有过程已经可以被其他过程引用。
- 用户可以分别修改一个过程在包体内的定义及在包规范中的声明。只要在包规范中的过程声明没有发生变化,引用了包中被修改过程的对象就不会被标志为无效状态[invalid]。因此避免了不必要的重新编译工作。
六、包的优势
使用包具有以下优势:
- 封装相关的过程与变量
使用存储包[stored package]用户可以将存储过程,变量,数据类型等程序结构封装[encapsulate](或称为组合)为一个命名的程序单元并存储在数据库中。这使开发过程更易管理。此外,将过程封装还能使权限管理更简单。当授予用户访问包的权限后,用户就可以访问包内的所有程序结构。 - 声明公有或私有的过程,变量,常量及游标
在定义包时,用户可以决定过程,变量,常量及游标是公有或私有的。公有的程序结构意味着其可以被用户直接使用。而私有程序结构对用户是不可见的。
例如,一个包中包含 10 个过程。用户可以将其中的 3 个声明为公有的,包用户可以直接使用。其余过程声明为私有,只能被包内的过程访问。注意,不要将公有及私有包程序结构与授权给 PUBLIC 相混淆。 - 性能更佳
当包内的某个过程第一次被调用时,整个包将被加载到内存中。这个加载操作只需执行一次,而对于分散的独立过程[standalone procedure]则需要执行多次操作。因此,当包内的其他过程被调用时其编译代码已经存在于内存中,而无需进行磁盘 I/O 操作。
包体可以被修改并重新编译而不会影响包规范。因此,引用(总是根据包规范进行引用)了包内被修改程序结构的方案对象无需重新编译,除非包规范也作了修改。使用包可以减少不必要的重新编译操作,从而减少了对数据库整体性能的影响。