触发器创建语法
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 触发条件]--触发条件
![](/qrcode.jpg)
[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'