plsql触发器异常包
2026/9/11 23:42:27 网站建设 项目流程


异常

1. 预定义异常

2. 非预定义异常

3. 自定义异常


1. 预定义异常 :是指 oracle 已经设定好的异常 包含 异常名 异常信息 异常代码


。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。


CASE_NOT_FOUND ----异常名

使用CASE语句时在WHEN子句中没有包含必需的条件分支,并且没有包含ELSE语句。
对应ORA-06592错误。---异常信息

-06592 ------异常代码


COLLECTION_IS_NULL
给集合元素赋值前,必需初始化集合元素。对应ORA-06531错误。

CURSOR_ALRADY_OPEN
重新打开已经打开的游标。对应ORA-06511错误。

DUP_VAL_ON_INDEX
在惟一索引所对应的列上键入重复值。对应ORA-00001错误。

INVALID_CURSOR
试图操作不合法的游标。对应ORA-01001错误。

INVALID_NUMBER
内嵌SQL语句不能有效的将字符转换成数字。对应ORA-01722错误。

NO_DATA_FOUND
执行SELECT INTO未返回行。对应ORA-01403错误。

TOO_MANY_ROWS
执行SELECT INTO语句时,返回超过一行。对应ORA-01422错误。

ZERO_DIVIDE
PL/SQL块中,使用数字除0,对应ORA-01476错误。

SUBscript__BEYOND_COUNT
元素下标超出嵌套表或VARRAY元素的范围。对应ORA-06533错误。

SUBscript__OUTSIDE_LIMIT
使用嵌套表或VARRAY元素时,元素下标为负。对应ORA-06532错误。

VALUE_ERROR
PL/SQL中赋值操作时,变量长度不足以容纳实际数据,或尝试将无效的字符串转换成数据。
对应ORA-06502错误。

LOGIN_DENIED
连接到ORACLE数据库时,用户名/密码不正确。对应ORA-01017错误。

NOT_LOGGED_ON
应用程序没有连接到数据库。对应ORA-01012错误。

PROGRAM_ERROR
PL/SQL内部问题。对应ORA-06510错误。

ROWTYPE_MISMATCH
执行赋值操作时,宿主游标变量和PL/SQL游标变量返回类型不兼容。对应ORA-06504错误。

SELF_IS_NULL
在NULL实例上调用成员方法。对应ORA-30625错误。

STORAGE_ERROR
PL/SQL块运行时超出了内存空间或者内存被破坏。

SYS_INVALID_ROWID
将字符串转变为ROWID时没有使用有效的字符串。对应ORA-01410错误。

TIMEOUT_ON_RESOURCE
ORACLE在等待资源时超时。对应ORA-00051错误。

TRANSACTION_BACKED_OUT
由于死锁提交被退回 对应ORA-006 错误。


---捕获异常

语法
declare


begin

exception -----只能捕获异常 不能修改异常
when 异常名 then 异常代码
when 异常名 then 异常代码
when 异常名 then 异常代码
when 异常名 then 异常代码
when 异常名 then 异常代码
when 异常名 then 异常代码
..................................................

end;


declare


begin
dbms_output.put_line(1/0);




exception
when ZERO_DIVIDE then
dbms_output.put_line('除数为0');

end;

未知异常: OTHERS
错误信息: SQLERRM
错误代码: SQLCODE


declare


begin
dbms_output.put_line(1/0);




exception
when OTHERS then
dbms_output.put_line(SQLERRM||' '||SQLCODE );

end;

--------------------------------------------------------------------

非预定义异常 : 没有名字 只有异常信息和异常代码


语法

declare
异常名 exception ; -----声明一个异常名

PRAGMA EXCEPTION_INIT(异常名,异常代码) ;
--第二步 将异常的名字和异常代码进行绑定


begin

exception
when 异常名 then
异常代码
........................

end;


-------------------------------
自定义异常 --没有名字 没有代码 没有信息 完全自定义

语法

declare
异常名 exception ; -----声明一个异常名
PRAGMA EXCEPTION_INIT(异常名,自定义代码) ; ---2 绑定代码 -20001 ~ - 20999

begin
raise_application_error(自定义代码,'自定义异常信息');---手动抛出异常

--自定义异常需要手动抛出




exception
when 异常名 then
异常代码
........................

end;


declare


begin
raise_application_error(-20001,'付浩浩'); ----手动抛出异常

end;


---------------------------------------------------------------
---------------------------------------------------------------------
触发器 trigger

定义 是 由 DML 语句 影响的 触发事件

创建触发器
语法

create [or replace] trigger 触发器名
before|after ------之前 之后

update or insert or delete ------用什么写什么

on 表名

[for each row ] ----------------行级触发器

begin
-----触发的事件 事情 内容

end;


行级触发器 -------是指 DML 语句 影响了多少行数据 触发器 就会触发多少次

delete from emp


表级触发器 ------表级 是指 无论 DML 语句影响了多少行数据 触发器 只会触发一次

例题 创建一个触发器 对 emp表进行增 删 改 则会触发触发器
触发事件 是
打印输出 修改了数据


create or replace trigger t_97

before

update or delete or insert

on emp

begin
dbms_output.put_line('修改了数据');----触发事件

end;

insert into emp(empno,ename) values(6789,'晁洪涛')

update emp set sal=1

delete from emp

create or replace trigger t_97

before

update or delete or insert

on emp

for each row

begin
dbms_output.put_line('修改了数据');----触发事件

end;

例题 创建一个触发器 对 emp表进行增 删 改 则会触发触发器
触发事件 是
插入数据的时候 打印输出 插入了数据
修改数据的时候 打印输出 修改了数据
删除数据的时候 打印输出 删除了数据

触发器的三个判断属性

deleting --判断当前操作是否为 delete 如果是则返回 true

updating --判断当前操作是否为 update 如果是则返回 true

inserting --判断当前操作是否为 insert 如果是则返回 true


create or replace trigger t_97
before
update or insert or delete
on emp
for each row

begin
if deleting then
dbms_output.put_line('删除了数据');
elsif updating then
dbms_output.put_line('修改了数据');
elsif inserting then
dbms_output.put_line('增加了数据');
end if;

end;


insert into emp(empno,ename) values(6789,'晁洪涛')

update emp set sal=1

delete from emp


select * from emp


----------------------------------------------------------
行级触发器 的两个属性

:old ----------------------修改前的数据

:new ----------------------修改后的数据


例题 创建一个触发器 修改emp表的工资 如果 修改前的工资小于修改后的薪资
则打印输出涨薪 否则 打印输出降薪

create or replace trigger t_97
before
update
on emp

for each row

begin
if :old.sal < :new.sal then
dbms_output.put_line('涨薪');
elsif :old.sal>:new.sal then
dbms_output.put_line('降薪');
else
dbms_output.put_line('不变');
end if;

end;


update emp set sal=3000

-----------------------------------------------------------


包 -------------一系列函数 和存储过程的集合

-----------------方便迁移 不容易乱


包头 package ---------标签 标明了 包里面的内容


包体 package body ---装东西

包头 package
创建语法

create [or replace] package 包名
is
----声明 要装的存储过程 和函数


end;


create or replace package 爱马仕

is
function fu_97(p_max number) return number ; ---声明 fu_97
function fu_96(V_deptno number) return number; ----fu_96

procedure sp_97(p_deptno in number,o_emp_count out number,o_avg_sal out number);--sp_97

end ;


创建包体


语法

create [or replace ] package body 包体名 ---和包头一致

is
-------------装

end;

create package body 爱马仕 ---和包头一致

is
-------------装
function fu_97(p_max number)
return number
is
n number:=0;
begin
for i in 1..p_max loop
if mod(i,2)=0 then
n:= n+ i;
end if;
end loop;

return n;
end;---fu_97

function fu_96(V_deptno number)
return number
is
V_avg number;
begin
select avg(sal) into V_avg from emp where deptno=V_deptno;

return V_avg;
end;--fu_96

procedure sp_97(p_deptno in number,o_emp_count out number,o_avg_sal out number)

is

begin
select avg(sal),count(1) into o_avg_sal,o_emp_count from emp where deptno=p_deptno;

if o_emp_count>5 then
o_avg_sal:= o_avg_sal*1.1;
end if;
end; ---sp_97
end;

select fu_96(10) from dual


select 爱马仕.fu_96(10) from dual


dbms_output.put_line( 1 )

----------------------------------------------------------------
------------------------------------------------------------------
------------------------------------------------------------------------
---------------------------------------------数据库的基础 sql plsql 结束


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询