PL/SQL (Procedural Language/SQL. 过程语言/SQL) 是结合了Oracle过程语言和结构化查询语 言(SQL)的一种扩展语言。使用PL/SOL可以编写具有很多高级功能的程序,虽然通过多个SQL 语句也能实现同样的功能,但是相比而言,PL/SQL 具有更为明显的一些优点。
PL/SQL具有编程语言的特点,它能把一组SQL语句放到一个模块中.使其更具模块化程序的特点。PL/SQL 可以采用过程性语言控制程序的结构,也就是说,我们可以在PL/SQL中增加逻辑结构,如判断、循环等程序结构。同其他的编程语言一样PL/SOL可以对程序中的错误进行自动处理,使程序能够在遇到错误时不会中断,即它的异常处理机制。PL/SQL程序块具有更好的可移植性,可以移植到另一个Oracle 数据库中。PL/SQL程序减少了网络的交互,有助于提高程序性能。P/SQL引擎用来编译和执行PL/SOL块或子程序,该引擎驻留在Oracle服务器中,PL/SOL引擎仅执行过程语句,而将SQL语句发送给Oracle服务器上的SQL语句执行器,由SQL语句执行器执行这些SOL语句。
PL/SQL是一种块结构的语言,它将一组语句放在一个块中。PL/SQL块将逻辑上相关的声明和语句组合在一起。匿名块是一个未在数据库中命名的PL/SQL块,在运行时被传递到PL/SQL引擎以便执行。在PL/SQL块中可以使用SELECT. INSERT. UPDATE. DELETE 等DML语句,事务控制语句及SQL函数等。PL/SQL 块中不允许直接使用CREATE. DROP 或ALTER等DDL语句,但可以通过动态SQL来执行它们。
[DECLARE]--声明开始关键字 /*声明部分,包括PL/SQL中的变量、常量以及类型等*/ BEGIN --执行部分开始的标志 /*这里是执行部分,是整个PL/SQL块的主体部分*/ [EXCEPTION] --异常开始部分的关键字 /*这里是异常处理部分*/ END; --执行结束标志
LOB 数据类型 Oracle 提供了 LOB (Large Object)类型,用于存储大的数据对象的类型。Oracle 目前主要支持 BFILE、BLOB、CLOB 及 NCLOB 类型。
属性类型 属性用于引用变量或数据库列的数据类型,以及表示表中一行的记录类型。PL\SQL 支持一下两种属性类型。
%type 定义一个变量,其数据类型与已经定义的某个数据变量(尤其是表的一列)的数据类型相一致,这时我们可以使用 %type 。 使用 %type 属性的优点在于: (1)可以不必知道所引用的数据库列的数据类型。 (2)所引用的数据库列的数据类型可以实时改变,容易保持一致,不用修改 PL/SQL 程序。
%rowtype 返回一个记录类型,其数据类型和数据库表的数据结构相一致,这时可以使用 %rowtype 。 使用 %rowtype 属性的优点在于: (1)可以不必知道所引用的数据库中列的个数和数据类型。 (2)所引用的数据库中列的个数和数据类型可以实时改变,容易保持一致,不用修改 PL/SQL程序。
条件控制 语法:
if <布尔表达式> then pl/sql或sql语句; end if; if <布尔表达式> then pl/sql或sql语句; else pl/sql或sql语句; end if; if <布尔表达式> then pl/sql或sql语句; elsif <布尔表达式> then pl/sql或sql语句; elsif <布尔表达式> then pl/sql或sql语句; else pl/sql或sql语句; end if;循环控制 语法:
loop 要执行的语句 exit when<条件语句> --满足条件则退出循环 end loop; while <布尔表达式> loop 要执行的语句; end loop; for 循环计数器 in [reverse] 下限 .. 上限 loop 要执行的语句; end loop 顺序控制 顺序控制用于按顺序执行语句。顺序控制包括 NULL 语句和 GOTO 语句。GOTO 语句不推荐使用。下面介绍NULL 语句。 NULL 语句: 是一个可执行语句,相当于一个占位符或不执行任何操作的空语句,它可以使某些语句变得有意义,提高程序的可读性,保证其他语句结构的完整性和正确性。 DECLARE v_counter NUMBER:=5; BEGIN DBMS_OUTPUT.put_line('v_counter的当前值为:'||v_counter); IF v_counter>=10 THEN NULL; ELSE v_counter:=v_counter+10; DBMS_OUTPUT.put_line('v_counter的改变后值为:'||v_counter); END IF; END;在运行程序时出现的错误叫做异常,发生异常后,语句将停止执行,控制权转移到 PL/SQL 块的异常处理部分。
语法:
begin 过程及sql语句; exception when <异常名称> then 过程及sql语句; when others then 过程及sql语句; END;1)声明游标
cursor cursor_name [ (parameter [,parameter]···') ] [return return_type] is select_statement; 其中 cursor_name:指游标的名称。 parameter:用于为游标指定输入参数。在指定数据类型时,不能使用长度约束。例如:number(4)、char(10) 等都是错误的。 return_type:用于定义游标提取的行的数据。 select_statement:指游标定义的查询语句。2)打开游标
open cursor_name [ (parameters) ];3)提取游标
fetch cursor_name into variables;其中 cursor_name:指游标的名称。 variables:指变量名。
4)关闭游标
close cursor_name;显示游标属性
使用显示游标删除或更新 语法:
cursor cursor_name is select_statement for update [of columns];在语法中: for update [of columns]为更新查询,锁定选择的行。 (1)当选择单表更新查询时,可以省略 of 子句; (2)当选择多个表更新查询时,被锁定的行来源于 of 子句后声明的列所在的表中的行。例如: 使用 for update of sal; ,则锁定 employee 表中的行,使用 for update of dname,则锁定dept表中的行。
在使用 for update 子句声明游标之后可以使用以下语法更新行。
update table_name set column_name = column_value where current of cursor_name在语法中: 多表查询更新时, 更新表为锁定行所在的表
子程序是已命名的 RL/SQL 块,它们存储在数据库中,可以为它们指定参数,也可以从任何数据库客户端和应用程序中调用它们。子程序包括存储过程和函数。使用存储过程执行操作,使用函数执行操作并返回值,就像应用程序中的方法—样。 与匿名的 PL/SQL 块一样,子程序具有声明部分、可执行部分、异常处理部分(可选)。
声明部分 声明部分包括类型、游标.常量、变量、异常和嵌套子程序的声明。这些项是局部的,退出子序后将不复存在。可执行部分 可执行部分包括赋值、控制执行过程及操纵 Oracle 数据的语句。异常处理部分 异常处理部分包括异常处理程序,负责处理执行存储过程中出现的异常。 子程序的优点如下。 模块化:通过子程序,可以将程序分解为可管理的、明确的逻辑模块。可重用性:子程序在创建并执行后,就可以在任意数目的应用程序中使用。可维护性:子程序可以简化维护操作,如果一个子程序受到影响,则只需修改该子程序的定义。安全性:用户可以设置权限,使得访问数据的唯一方式就是通过用户提供的存储过程和函数。这不仅可以让数据更加安全,而且可以保证它的正确性。在语法中: procedure _name:存储过程的名称。 parameter_list:参数列表,可选。 local_declarations:局部声明,可选。 executable_statements:可执行语句。 exeception_handlers:异常处理程序,可选。 or replace:可选。如果不包含 or replace 语句,则表示仅仅新建一个存储过程,如果系统存在该存储过程,则会报错;如果包含 or replace 语句,则表示如果系统中没有此存储过程则新建,有就用现在的替换原来的存储过程。
示例
DECLARE CURSOR emp_cursor IS SELECT ename,sal FROM employee; BEGIN FOR emp_record IN emp_cursor LOOP DBMS_OUTPUT.put_line ('第'||emp_cursor%ROWCOUNT||'个员工'||emp_record.ename||emp_record.sal); END LOOP; END; 调用存储过程 begin --按位置传递参数 add_employee(2111,'mary',2000,'manager',10); --按名字传递参数 add_employee(dno>=10,name>='mary',salary>=2000,eno>=2112,job>='manager'); --混合方式传递参数 add_employee(3111,dno>=10,name>='mary',salary>=2000,job>='manager'); end; 存储过程的参数模式 调用程序是通过参数向被调用的存储讨程传递值的。参数传递的模式有三种:IN、 OUT 和 IN OUT,即输入参数,输出参数和输入/输出参数。in 模式只能将实参传递给形参,进入函数内部,但只能读不能写,函数返回时实参的值不变,out 模式会忽略调用时的实参值(或说该形参的初始值总是NULL),但在函数内部可以被读或写,函数返回时形参的值会赋给实参。in out 具有前两种模式的特性,即调用时,实参的值总是传递给形参;结束时,形参的值传递给实参。 parameter_name [ in | out | in out ] datatype [ {:= | default} expression ]in 模式是默认参数传递模式。如果未指定参数的模式,则认为该参数是 in 参数。而对于 out 和 in out 参数,必须明确指定 out 和 in out。 在返回到调用环境之前,必须先给 out 或 in out 参数赋值。 可以在参数列表中为 in 参数赋予一个默认值,但不能为 out 、 in out 参数赋予默认值。
存储过程的访问权限 存储过程创建之后,只有创建该存储过程的用户和管理员才有权调用它。其他用户如果要调用该存储过程,需要得到存储过程的 execute 权限。 GRANT EXECUTE ON add_employee TO A_oe; REVOKE EXECUTE ON add_employee TO A_oe; 删除存储过程 drop procedure procedure_name; --procedure_name:存储过程名称