一、PL/SQL异常处理
1、异常的捕捉是从上到下的顺序。
2、异常处理语法为:"EXCEPTION WHEN 异常一[OR 异常二……] THEN 语句 …… WHEN OTHERS THEN 语句",如:
SQL>DECLARE
v_name emp.ename%TYPE:='&name';
v_job emp.job%TYPE;
BEGIN
SELECT job INTO v_job
FROM emp
WHERE ename=v_name;
EXCEPTION /*异常处理*/
WHEN NO_DATA_FOUND THEN /*数据不存在时的异常*/
dbms_output.put_line('没有这个员工!');
WHEN TOO_MANY_ROWS THEN /*数据过多时的异常*/
dbms_output.put_line('有多个员工叫SCOTT!');
WHEN OTHERS THEN
dbms_output.put_line('其他异常!');
END;
3、WHEN OTHERS一般是最后一条子句,如果前面没有捕捉到的异常都会被这个子句捕捉。
4、非预定义异常:这种异常通常是数据库的错误,这些错误只有错误编号没有错误的异常名称,所以不能直接捕捉,要捕捉需创建一个异常名称,并把名称与错误编号关联起来,如:
--捕捉预定义异常
SQL>DECLARE
e_emp_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT (e_emp_remaining,12292); /*将异常名与错误编号绑定*/
BEGIN
DELETE FROM dept WHERE deptno=10;
EXCEPTION /*异常处理*/
WHEN e_emp_remaining THEN /*数据不存在时的异常*/
ROLLBACK;
dbms_output.put_line('错误码为:'SQLCODE||',错误信息为:'||SQLERRM); /*此处SQLCODE与SQLERRM用来显示当前PL/SQL程序块的错误码和错误信息*/
WHEN OTHERS THEN
dbms_output.put_line('其他异常!');
END;
5、用户自定义异常是指当数据库的一些情况不符合用户的业务逻辑规定时,用户人为判断的异常,如人数不能为负数。通过调用RAISE命令捕捉异常,如"IF 字段名 IS NULL THEN RAISE 自定义异常"。
二、PL/SQL程序单元
1、PL/SQL程序单元包括四种:过程(用于执行特定操作和任务);函数(进行复杂计算,返回计算的结果);包(将逻辑上相关的过程和函数组织在一起,便于对PL/SQL程序进行管理);触发器(由
某些事件触发,执行相应操作任务)。
2、过程(PROCEDURE):如果在应用系统中经常需要执行某个操作,可以基于这些操作建立一个过程。
3、创建过程的语法"CREATE [OR REPLACE] PROCEDURE 过程名(参数名) IS 变量、常量声明;",如:
--创建过程,注意此处参数的传值类型,可以有三种方式(IN|OUT|IN OUT)
SQL>CREATE OR REPLACE PROCEDURE change_salary(v_empno IN NUMBER, v_new_salary IN NUMBER) /*存储过程名称相当于方法名*/
IS
v_count NUMBER;
BEGIN
…………
END;
4、作为IN类型参数传进来的参数,不能在子程序内部进行赋值修改操作;
create or replace procedure sp_t(idd in number)
is
begin
idd :=7;
end;
--这样会报错
5、作为OUT、IN OUT 类型参数传进来的时候,调用的实际参数必须是一个变量,不能直接用常量。
create or replace procedure sp_t(idd in out number)
is
begin
…………
end;
--注意看调用
declare
id_s number :=3;
begin
sp_t(id_s); --right
sp_t(3); --wrong
end;
6、如果在创建过程中提示带有编译错误,可以用SHOW ERROR查看错误信息。
7、存储过程创建之后,直接用"EXEC 过程名(参数值)"调用。
8、在数据字典中查看存储过程"SELECT object_name FROM user_objects WHERE object_type='PROCEDURE'"。查看过程源码"SELECT line,text FROM user_source WHERE name='要查看的存储过程名'"。
9、删除存储过程"DROP PROCEDURE 存储过程名"。
10、两种传参方式,一是按照参数的位置直接传参,二是通过"形参名=>实参名"符号用参数名传参,形参先有值,实参后有值。
11、创建函数(FUNCTION)的语法"CREATE OR REPLACE FUNCTION 函数名(参数名) RETURN 数据类型 IS 变量、常量声明;"。
12、在函数的头部末尾需加入RETURN语句说明函数的返回值类型。
13、函数中不能包含对数据库执行操作的语句,如DML语句,但在执行操作语句时可以调用函数。
14、在PL/SQL程序的执行块中必须至少包含一个有效的RETURN语句,如:
--创建函数
SQL>CREATE OR REPLACE FUNCTION tax(v_value IN NUMBER) /*此处传参用法同存储过程*/
RETURN NUMBER
IS
BEGIN
IF v_value<2000 THEN
RETURN (v_value*.10); /*必须要返回NUMBER类型的值*/
ELSE
RETURN (v_value*.20);
END IF;
END tax;
15、PL/SQL中自己定义的函数与oracle内置的函数如SUM、ROUND等作用一样,使用方法也一样。
16、在数据字典中查看函数"FUNCTION 函数名 RETURNS NUMBER",查看函数源码同存储过程。
17、删除函数"DROP FUNCTION 函数名"。
三、包
1、包是一组相差的存储过程、函数、变量、常量的集合,作用控制对存储过程、函数、变量、常量的公用与私用的权限。
2、包头的语法结构"CREATE [OR REPLACE] PACKAGE 包头名 {IS|AS} 公开类型定义; 公开变量、常量声明; 公开过程或函数声明; 公开异常声明; 公开游标声明; END 包头名;"。
3、包体的语法结构"CREATE [OR REPLACE] PACKAGE BODY 包体名 AS 私有类型定义; 私有变量、常量声明;私有过程或函数声明; 私有异常声明; 私有游标声明; END 包体名;"。
4、在包头声明的是外部可以调用的过程、函数、变量,也就是包公开的声明。但在包体内定义的过程、函数、变量是只能在包体内可见,这些声明是包体私有的声明。
5、包头必须在包体之前创建,包头必须存在,包体可不存在。
6、调用包内函数,必须"用包名.函数名(参数值)"这种方式。引用别的用户的包中的函数,必须是"用户名.包名.函数名(参数值)",调用过程的使用方式一样。
7、在数据字典中查看包"SELECT object_name FROM user_objects WHERE object_name='包名'",查看包的源码同存储过程。
8、删除包"DROP PACKAGE 包名"。