异常
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 结束