PLSQL触发器
Posted 张欣橙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PLSQL触发器相关的知识,希望对你有一定的参考价值。
触发器创建语法
CREATE OR REPLACE TRIGGER 触发器名称--创建触发器
[BEFORE|AFTER]--触发时间
[INSTEAD OF]--替代触发器
[INSERT|UPDATE|UPDATE OF 列名称|DELETE]--触发事件
ON [表名称|视图|DATABASE|SCHEMA]--触发对象
[REFERENCING[OLD AS 标记][NEW AS 标记][PARENT AS 标记]--三个标识符起别名
[FOR EACH ROW]--行级触发
[FOLLOWS 触发器名称]--多触发器执行顺序
[DISABLE]--默认启用(可禁用)
[WHEN 触发条件]--触发条件
[DECLARE]
[程序声明部分:]--触发器主题程序声明部分(定义游标或变量)
[PRAGMA AUTONUMOUS_TRANSACTION;]--子事物,可提交
BEGIN
程序代码部分--程序主体部分
END 触发器名称--触发器结束标记
/--完结标记
操作顺序
BEFORE表级触发器执行;
BEFORE行级触发器执行;
执行更新操作
AFTER 行级触发器执行;
AFTER 表级触发器执行;
触发器范例
create table emp_x as select * from emp;
create or replace trigger forbid_emp_x_trigger
before insert or delete
on emp_x
declare
v_currentdate varchar(20);
begin
select to_char(sysdate,\'dd\') into v_currentdate from dual;
if trim(v_currentdate)!=\'10\' then
raise_application_error(-20008,\'10th of every month is ok\');
end if;
end;
/
在星期一,周末以及每天下班时间不能够修改EMP表数据
create or replace trigger forbid_emp_x_trigger2
before insert or delete or update
on emp_x
declare
v_currentweak varchar(20);
v_currenthour varchar(20);
begin
select to_char(sysdate,\'day\'),to_char(sysdate,\'hh24\') into v_currentweak,v_currenthour from dual;
if trim(v_currentweak)=\'monday\' or trim(v_currentweak)=\'saturday\' or trim(v_currentweak)=\'sunday\' then
raise_application_error(-20008,\'can not update emp on mon/sat/sun\');
elsif trim(v_currenthour)<9 or trim(v_currenthour)>18 then
raise_application_error(-20009,\'can not update emp after 18:00 or before 9:00\');
end if;
end;
/
在每天12点以后,不允许修改雇员工资和佣金
create or replace trigger forbid_emp_trigger3
before update of sal,comm
on emp
declare
currenthour varchar(20);
begin
select to_char(sysdate,\'hh24\') into currenthour from dual;
if trim(currenthour)>\'12\' then
raise_application_error(-20009,\'can not update sal and comm\');
end if;
end;
/
定义触发器
BEFORE薪水佣金表级触发器(BEFORE UPDATE OF SAL,COMM)
设置在EMP表
定义变量
把当前日期输入到变量里
如果变量大于12,则报错
表级触发器是在执行DML语句时触发
行级触发器 FOR EACH ROW
create or replace trigger forbid_emp_x_trigger4
before insert
on emp_x
for each row
declare
v_jobcount number;
begin
select count(empno)into v_jobcount from emp where :new.job in(select distinct job from emp);
if v_jobcount=0 then raise_application_error(-208,\'zjdgyzwxxcw\');
else
if:new.sal>5000 then raise_application_error(-208,\'zjgydgzbdcg5000\');
end if;
end if;
end;
/
工资涨幅不能超过10%
create or replace trigger emp_update_trigger5
before update of sal
on emp_x
for each row
begin
if abs((:new.sal-:old.sal)/:old.sal)>0.1 then
raise_application_error(-20008,\'too much increase\');
end if;
end;
/
update emp_x set sal=5000 where empno=7566;
update emp_x set sal=5000 where empno=7566
*
ERROR at line 1:
ORA-20008: too much increase
ORA-06512: at "SCOTT.EMP_UPDATE_TRIGGER5", line 3
ORA-04088: error during execution of trigger \'SCOTT.EMP_UPDATE_TRIGGER5\'
不能删除所有10号部门的雇员
create or replace trigger emp_delete_trigger6
before delete
on emp_x
for each row
begin
if:old.deptno=10 then
raise_application_error(-20008,:old.empno||\'deptno=10,can not delete\');
end if;
end;
/
delete emp_x where deptno=10;
delete emp_x where deptno=10
*
ERROR at line 1:
ORA-20008: 7782deptno=10,can not delete
ORA-06512: at "SCOTT.EMP_DELETE_TRIGGER6", line 3
ORA-04088: error during execution of trigger \'SCOTT.EMP_DELETE_TRIGGER6\'
在增加雇员时,判断雇员工资是否存在,如果工资为0则报错
create or replace trigger emp_insert_trigger8
before insert
on emp_x
for each row
when(new.sal=0)--使用when字句的时候可以不加:
begin
raise_application_error(-20008,:new.empno||\'salary is 0\');
end;
/
要求工资只能上涨 不能下降
create or replace trigger emp_insert_trigger8
before update
on emp_x
for each row
when(new.sal<old.sal)
begin
raise_application_error(-20008,:new.empno||\'salary can not be lower\');
end;
/
update emp_x set sal=2800 where empno=7566;
update emp_x set sal=2800 where empno=7566
*
ERROR at line 1:
ORA-20008: 7566salary can not be lower
ORA-06512: at "SCOTT.EMP_INSERT_TRIGGER8", line 2
ORA-04088: error during execution of trigger \'SCOTT.EMP_INSERT_TRIGGER8\'
以上是关于PLSQL触发器的主要内容,如果未能解决你的问题,请参考以下文章