4.1.1 PL/SQL概述
PL/SQL是Oracle在标准SQL语言上的过程性扩展,它允许嵌入SQL语句、定义变量和常量、使用过程语言结构(条件分支语句和循环语句)、使用异常来处理Oracle错误等。在任何运行Oracler的平台上,应用开发人员都可以使用PL/SQL。通过使用PL/SQL,可以在一个PL/SQL块中包含多条SQL语句和PL/SQL语句。PL/SQL可以用于创建存储过程、触发器和程序包等,也可以用于处理业务规则、数据库事件或为SQL命令的执行添加程序逻辑。
PL/SQL是一种可移植的高性能事务处理程序,它支持SQL和面向对象编程,提供了良好的性能和高效的处理能力,具有以下6个方面的优点。
1.提高应用程序的运行性能
在编写OracoeOracle数据库应用程序时,开发人员可以直接将PL/SQL块内嵌到应用程序中,其最大的优点是可以降低网络开销、提高应用程序性能。对于其他异构数据库(例如SQL Server、Sybase、DB2等),当应用程序访问RDBMS时,每次只能发送单条SQL语句。而对于Oracle数据库而言,通过使用PL/SQL块,可以将多条SQL语句组织到同一个PL/SQL块中,从而降低网络开销,提高应用程序的性能。
2.提供模块化的程序设计功能
当开发数据库应用程序时,为了简化客户端应用程序的开发和维护工作,可以首先将企业规则或商业逻辑集成到PL/SQL子程序(过程、函数和包)中,然后在应用程序中调用子程序实现相应的程序功能。
3.允许定义标识符
当使用PL/SQL开发应用模块时,为了使应用模块与应用环境实现数据交互,需要定义变量、常量、游标等各种标识符。例如,函数get_sal中的no为输入参数,用于接收雇员编号的输入值,而salary变量则用于临时存储雇员工资。
4.具有过程语言控制结构
PL/SQL是Oracle在标准SQL上的过程性扩展,它不仅允许在PL/SQL块中嵌入SQL语句,而且允许在PL/SQL块中使用各种类型的条件分支语句和循环语句。
5.具有良好的兼容性
PL/SQL是Oracle提供的用于实现应用模块的语言,在允许运行Oracle的任何平台上都可以使用PL/SQL。例如,在Oracle数据库中使用PL/SQL开发数据库端的过程、函数和触发器,以及在Oracle提供的应用开发工具Developer中使用PL/SQL开发客户端的过程、函数和触发器。
6.处理运行错误
当设计并开发应用程序时,为了提高应用程序的健壮性,可以使用PL/SQL提供的异常处理(EXCEPTION)集中处理各种Oracle错误和PL/SQL错误,从而简化错误处理。
4.1.2 PL/SQL块所有的PL/SQL程序都以块作为基本单位组成。块中包含过程化语句和SQL的DML语句。这些块可以按顺序出现,也可以相互嵌套(一个块在别一个块的内部)。按是否带有名称以及在数据库中的存储方式,块可以分为以下5种。
1.匿名块
匿名块是出现在应用程序中的没有名称且不存储到数据库中的块。匿名块可以出现在SQL语句出现的地方,它们可以调用其他程序,却不能被其他程序调用。
2.命名块
命名块是一种带有标签的匿名块,标签为块指定了一个名称。
3.子程序
子程序是存储在数据库中的过程(procedure)、函数(function),生成之后可以被多次执行。
4.程序包
程序包是存储在数据库中的一组子程序、变量定义。程序包中的子程序可以被其他程序包或者子程序调用。如果声明为局部子程序,则只能在定义该局部子程序的块中被调用该局部子程序。
5.触发器
触发器是一种存储在数据库中的命名块,生成之后可以被多次执行。在相应的触发器事件发生之前或之后就会被执行一次或多次(每行记录一次)。触发器事件一般是指对特定的数据库表、视图进行的操作,如INSERT、UPDATE和DELETE等(被称为DML触发器);或者对数据库级的操作,如关闭、启动、登录、退出数据库,创建对象、修改对象、删除对象等(称为系统触发器)。
4.2 程序结构4.2.1 组成部分和注释
PL/SQL程序块由3个部分组成:定义部分、执行部分和异常处理部分。其中,定义部分用于定义常量、变量、游标、异常和复杂数据类型等;执行部分用于实现应用模块功能,该部分包含需要执行的PL/SQL语句和SQL语句;异常处理部分用于处理执行部分可能出现的运行错误。PL/SQL块的基本结构如下:
DECLARE
定义部分
BEGIN
执行部分
EXCEPTION
异常处理部分
END;
其中,定义部分以DECLARE开始,该部分是可选的;执行部分以BEGIN开始,该部分是必须的;异常处理部分以EXCEPTION开始,该部分是可选的;END则是PL/SQL程序块的结束标记。以下示例创建匿名程序块,用于接收用户输入的员工编号,输出该员工的姓名,以及处理用户输入的员工编号不存在的异常
注意
DECLAREE、BEGIN和EXCEPTION后面没有“;”(分号),而END后则必须要带“;”(分号)。
在PL/SQL程序中加入注释可以帮助理解程序,PL/SQL编译器在编译时会忽略注释,PL/SQL的注释分为单行注释和多行注释。
1.单行注释
单行注释可以放在一行的任何地方,由两条短横线(--)开始。
2.多行注释
多行注释“/*”开始、“*/”结束,可以跨越多行,但不允许嵌套。
在调试PL/SQL程序时,完全可以使用单行或多行注释来将暂时不需要或不正确的语句进行注释或禁用。
4.1.1 常量与变量在声明部分中可以声明需要使用的常量、变量、函数、游标、异常处理名称等。
1.声明
声明常量、变量的语法如下:
语法:
Iidentifier_name [CONSTANT] data_type [NOTNULL][:=value_expression]|[DEFAULT value_expression]其中,identifier_name指定需要声明的常量、变量的名称;data_type指定数据类型;“:=”是赋值运算符(或使用DEFAULT);value_expression是赋值表达式。如果语句中有CONSTANT,则表明声明的是一个常量;如果有NOT NULL,则表明声明的变量是不能为空(即在声明时必须赋值)。声明常量时应该立即赋值,如果没有赋值则表示初始化为NULL。
注意:
在PL/SQL中,每一行中能声明一个常量或变量。在引用一个常量或变量之前,必须先对其进行声明。
2.使用SELECT INTO语句为变量赋值
除了可以使用常量为变量赋值之外,还可以将从数据库表中查询获得的值赋给变量。通过SELECT INTO语句可以从数据库表中查询的结果赋予变量,根据雇员编号获得雇员工资、补助和总工资,代码如图4.1.1所示。该示例代码中,从数据库中根据员工编号查询员工姓名,并把员工姓名赋给变量v_ename。
4.1.1 数据类型编写PL/SQL程序时,若临时存储数值,则必须定义变量和常量;若在应用环境和子程序之间传递数据,则必须为子程序指定参数。而在PL/SQL程序中定义变量、常量和参数时,必须为它们指定PL/SQL数据类型。常见的数据类型如表14-1-1所示。
表14-1-1 部分数据类型及说明
数据类型
说明
char
表示固定长度字符串,长度不够时使用空格来补充,最多可以存储2000字节。
varchar2
表示可变长字符串,最多可以存储4000字节。
number
可以存储正数、负数、零、定点数和精度为38的浮点数。其格式为:number(m,n),其中m表示精度代表数字的总位数;n表示小数点右边数字的位数。
date
用于存储表中的日期和时间数据,取值范围是公元前4712年1月1日到公元9999年12月31日。Date类型的长度是7,7个字节分别表示世纪、年、月、日、时、分和秒。
timestamp
用户存储日期的年、月、日、小时、分和秒值。其中,秒值精确到小数点后6位数,该数据类型同时包含时区信息。
clob
用于存储可变长度的字符数据,最多可存储4GB。该数据类型用于存储varchar2类型不能存储的长文本信息。
blob
用于存储较大的二进制对象,如图形、视频剪辑和声音剪辑等,该类型最多可存储4GB数据。
PL/SQL中的数据类型除了表1-1-1所列出的以外还有以下常用的类型:
1.%TYPE
当定义PL/SQL变量存放值时,必须确保变量使用合适的数据类型和长度,否则可能在运行过程中出现PL/SQL运行错误。此时,可以使用%TYPE属性来定义变量。当使用%TYPE属性定义变量时,Oracle会自动地按照数据库列或其他变量来确定新变量的类型和长度。图4.1.3演示了使用%TYPE定义变量的过程。
2.%ROWTYPE
如果一张表中包含较多的列,则可以使用%ROWTYPE来定义一个表示表中一行记录的变量,这样比分别使用%TYPE来定义表示表中各个列的变量理更加简洁。为了使一个变量的数据类型与一张表中记录的各个列的数据类型对应一致,Oracle提供了%ROWTYPE定义定议方式。
在图4.1.3中,根据输入的员工编号查询该员工姓名、部门编号,并将查询结果存储在变量v_ename、v_deptno中。然后根据根据部门编号查询一条部门信息并将该信息存入变量v_dept_row中。
3.RECORD
PL/SQL记录类似于高级语言中的结构,每个PL/SQL记录一般都包含多个成员。当使用PL/SQL记录时,首先需要在定义部分定义记录类型和记录变量,然后在执行部分引用该记录变量。当引用记录成员时,必须将记录变量作为前缀,格式为“记录变量.记录成员”。
语法:
Type record_name is record
(
V1 data_type1 [not null] [:=default_value],V2 data_type2 [not null] [:=default_value],
Vndata_typen [not null] [:=default_value]
);
4.TABLE
索引表相当于一个键值集合,键是唯一的,用于查找对应的值。键可以是整数或字符串。
语法:
Type table_name is table of element_type [not null]index by [binary_integer | pls_integer |varchar2]
关键字INDEX BY表示创建一个主键索引,以便引用记录表变量中的特定行。
4.1 流程控制流程控制是PL/SQL对SQL最重要的扩展,流程控制结构包括条件控制、循环控制和顺序控制。
4.1.1 条件控制在许多情况中,需要按照某种条件来选择执行某些语句段。条件控制先测试一个条件,然后根据测试的结果选择、运行不同的语句段。条件结构中允许嵌套。
1.IF…THEN…END IF结构
最简单的条件控制结构。
语法:
If IF 条件表达式 THEN
语句段
END IF;
2.IF…THEN…ELSE…END IF结构
二重条件分支结构。如果满足条件则执行一组操作,不满足条件则执行另外一级组操作。
语法:
IF 条件表达式 THEN
语句段1
ELSE
语句段2
END IF;
3.IF…THEN…ELSIF…END IF结构
多重条件分支结构。如果满足第一个条件,则执行第一种操作;如果不满足第一个条件,则检查是否满足第二个条件,如果满足则执行第二种操作;如果不满足第二个条件,则检查是否满足第三个条件……依此类推。
语法:
IF 表达式1 THEN
语句段1
ELSIF 条件表达式2 THEN
语句段2
……
ELSIF 条件表达式n THEN
语句段n
ELSE
语句段
END IF ;