字体:Courier New 大小 10
4.PLSQL异常处理
Exception是一种PL/SQL标识符,当运行的PL/SQL块出现错误或警告,则会触发异常处理。为了提高程序的健壮性,可以在PL/SQL块中引入异常处理部分,进行捕捉异常,并根据异常出现的情况进行相应的处理。Oracle异常分为两类:系统异常、自定义异常(其中系统异常又分为:预定义异常和非预定义异常)
--异常处理
declare
sNum number := 0;
begin
sNum := 5 / sNum;
dbms_output.put_line(sNum);
exception
when others then
dbms_output.put_line('is Error!');
end
1.预定义异常
--演示一个整除的异常
DECLARE
v_n1 NUMBER:=50;
v_n2 NUMBER:=0;
v_n3 NUMBER;
BEGIN
v_n3:=v_n1/v_n2;
DBMS_OUTPUT.PUT_LINE('v_n3='||v_n3);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('v_n2 don't is 0');
END;
/
--演示VALUE_ERROR
declare
v_ename varchar2(3);
begin
select ename into v_ename from emp where empno=&eno;
dbms_output.put_line(v_ename);
exception
when value_error then
dbms_output.put_line('variable datatype length is small');
end;
--演示TOO_MANY_ROWS
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where deptno=&dno;
exception
when too_many_rows then
dbms_output.put_line('Too many rows are returned');
end;
2.非预定义异常
3. 自定义异常
a.定义一个异常名
b.将异常名与异常编号相关联
c.在异常处理部分捕捉并处理异常
declare
ex_custom_error exception;
pragma exception_init(ex_custom_error, -1);
--把一个编号和一个自定义异常关联,
--相当于把-1编号的异常命名为ex_custom_error,这样就可以捕获这种异常
begin
insert into dept values(10, 'aaa', 'bbb');
exception
when ex_custom_error then
dbms_output.put_line('部门编号已经存在');
end;
a.定义异常(在declare部分进行定义)
b.显示触发异常(在执行BEGIN部分触发异常,使用RAISE语句)
c.引用异常(在EXCEPTION部分捕捉并处理异常)
declare
ex_custom_invaild_age exception; --自定义的异常myerr
age int;
begin
age := &请输入年龄;
if (age < 0) then
raise ex_custom_invaild_age; --引发自定义异常
else
dbms_output.put_line('年龄是:' || age);
end if;
exception
when ex_custom_invaild_age then
dbms_output.put_line('非法的年龄');
end;
--引发应用程序异常
--raise_application_error(异常编号,说明);
declare
age int;
begin
age := &请输入年龄;
if (age < 0) then
raise_application_error(-20500, '年龄不能为负数');
else
dbms_output.put_line('年龄是:' || age);
end if;
end;
5.PLSQL事务处理
事务也称工作单元,是一个或多个SQL语句所组成的序列,这个SQL操作作为一个完整的工作单元,要么全部执行,要么全部不执行。通过事务的使用,能够使一系列相关操作关联起来,防止出现数据不一致现象。典型的例子就是储户的转账活动,就需要把两个动作定义在一个事务中,那么两个操作将同时成功或同时失败,从而保证了数据的一致性。
事务有以下语句组成:(1)一组相关的DML(数据操纵语言)语句,修改的数据在该组语句中保持一致。(2)一个DDL语句或DCL语句(数据定义语言)。
事务的特征:
(1)原子性
(2)一致性
(3)隔离性,防止同时的读和写操作。
(4)持久性
事务控制:
(1)事务提交:commit
(2)事务回滚:rollback to 保存点名称
(3)设立保存点:savepoint 保存点名称
每个修改语句完成后都可以回滚或提交,即rollback、commit;
eg:
insert into dept values(50, 'soft', 'Guangzhou');
rollback;
这样就回滚了,等于上面的没有插入;如果commit就提交了,此后如果再rollback也无力回天了。
下面这样也是无法回滚的:
insert into dept values(50, 'soft', 'Guangzhou');
create table temp as select * from dept;
rollback;
再次查询,发现无法回滚;同样增删改后面运行grant/create语句也是无法回滚的;
6.PLSQL锁
事务需要使用锁来防止一个用户修改其他用户还没完成事务的数据。对多用户数据来说,锁机制是必须的。锁用来锁定相关资源,锁归事务所有;锁是数据库用来控制共享资源并发访问的机制.锁用于保护正在被修改的数据。在事务开始或开始后的某一时刻,事务依情况取得相应的锁,直到事务结束事务所持有的所有的锁才被释放
锁定的特点
并行性 -允许多个用户访问同一数据
一致性 - 一次只允许一个用户修改数据
完整性 - 为所有用户提供正确的数据。如果一个用户进行了修改并保存,所做的修改将反映给所有用户
锁的分类:
行级锁:对正在被修改的行进行锁定。其他用户可以访问除被锁定的行以外的行顾名思义行锁不会锁住整张表,它仅锁住相关行,行锁都是排它的。
一般的查询语句如select ... from ...语句影响的行不会被锁住,但select ... from ... for update语句影响的行会被行级排它锁住。其他事务只能查询这些数据行,不能进行update、delete或select...for update操作。insert / update / delete ...语句影响的行会被行级排它锁住。其他事务只能查询这些数据行,不能进行update、delete或select...for update操作。
表级锁:锁定整个表,限制其他用户对表的访问
--->表级共享锁LOCK TABLE <table_name> IN SHARE MODE
该语句将在<table_name>上设置表级共享锁。该锁设置之后,其他事务仅能查看<table_name>表,不能增、删、改。<table_name>表,其他事务可同时放置表级共享锁于<table_name>表上。
--->表级排它锁LOCK TABLE <table_name> IN EXCLUSIVE MODE
表级排它锁与表级共享锁非常相似,但每次只有一个用户可以在表中放置排它锁,却可以有多个用户同时在同一个表中放置共享锁。
带有for update子句的select语句可以在表的一行或多行设置排它锁。
事务阻塞 :
当A事务锁住了某种资源,而同时B事务发出对这种资源的修改语句,则B事务将会被阻塞
我们可规定等待他事务释放锁的等待时间,如:
select ... from ... for update wait 10; ------将会等待10秒
LOCK TABLE table1 IN EXCLUSIVE MODE NOWAIT;
死锁:
当两个事务相互等待对方释放资源时,就会形成死锁
Oracle会自动检测死锁,并通过结束其中的一个事务来解决死锁