定义:触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。(特定事件出现的时候,自动执行的代码块。)
功能:
1、 允许/限制对表的修改
2、 自动生成派生列,比如自增字段
3、 强制数据一致性
4、
提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑
ORACLE产生数据库触发器的语法为:
create [or replace] trigger 触发器名 触发时间 触发事件
on
表名
[for each row]
pl/sql 语句
其中:
触发器名:触发器对象的
名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:
before---
表示在数据库动作之前触发器执行;
after---表示在数据库动作之后出发器执行。
触发事件:指明哪些数据库动作会触
发此触发器:
insert:数据库插入会触发此触发器;
update:数据库修改会触发此触发器;
delete:
数据库删除会触发此触发器。
表 名:数据库触发器所在的表。
for each
row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次。
举例:下面的触发器在更新表auths之前触发,目的是
不允许在周末修改表:
create trigger auth_secure
before insert or
update or delete //对整表更新前触发
on auths
begin
if(to_char(sysdate,'DY')='SUN'
RAISE_APPLICATION_ERROR(-20600,'
不能在周末修改表auths');
end if;
end
触发器可以包括任何合法的PL/sQL语句,假有以下例外
1.触发器不可以执行COMMIT、ROLLBACK或
SAVEPOINT语句,而且不可以调用执行这些语句之一的函数或过程。
2.触发器不可以声明long或LONG RAW变量。
3.触发
器不可以在定义它的表上执行DML操作。CREATE OR REPLACE TRIGGER TRI_KCYXZ1_SFJCHZ
BEFORE update or
insert on KCYXZ1
for each row
declare PJLX varchar2(1);
begin
PJLX:=:NEW.KCYXZ1_PJLX;
IF
(PJLX='M') THEN
:NEW.KCYXZ1_SFJCHZ:='0';
END
IF;
end;
来替换操作表的update
异常解决:
解决:通过declare PRAGMA AUTONOMOUS_TRANSACTION,
保证每行插入动作为自治事务,必须加上commitExample:
create or replace trigger tr_road_name_no_i_u
after insert or update on road
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION; v_count number;
begin
select count(1)
into v_count
from road t
where t.name <> :new.name
and t.no = :new.no
and (t.xh > :new.XH or t.xh < :new.XH);
if v_count > 0 then
raise_application_error(-20056, 'aaaaaaaaaaaa');
end if;
select count(1)
into v_count
from road t
where t.name = :new.name
and t.no <> :new.no
and (t.xh > :new.XH or t.xh < :new.XH);
if v_count > 0 then
raise_application_error(-20056, 'bbbbbbbbbbbb');
end if;
commit;end tr_i_u_road;
下边是在网上搜索的,蛮好的设计想法,通过自己测试,可以通过,贴出来,作为参考:
使用临时表
11:04:36 SQL> CREATE GLOBAL
TEMPORARY TABLE Tmp(
11:04:39 2 rid
varchar2(20))ON COMMIT DELETE ROWS;
表已创建。
已用时间: 00: 00: 00.16
11:07:30 SQL>
create or replace trigger trg_tb
11:07:36 2
after insert on tb
11:07:36 3 for each
row
11:07:36 4 begin
11:07:36 5
if :new.col2='laji' then
11:07:36 6
insert into tmp values(:new.rowid);
11:07:36 7
end if;
11:07:36 8 end trg_tb;
11:07:36 9 /
触发器已创建
已用时间: 00: 00: 00.47
11:07:36 SQL> create or
replace trigger trg_tb_del
11:07:44 2 after
insert on tb
11:07:46 3 begin
11:07:46 4 delete from tb where exists(select 1
from tmp where rid=tb.rowid);
11:07:46 5
end trg_tb_del;
11:07:46 6 /
触发器已创建
已用时间: 00: 00: 00.31
11:08:59
SQL> select count(1) from tb;
COUNT(1)
----------
22
已用时间: 00: 00: 00.00
11:09:08 SQL>
insert into tb(col1,col2) values('aaa','laji');
已创建 1 行。
已用时间: 00: 00: 00.00
11:09:12 SQL> select count(1) from tb;
COUNT(1)
----------
22
已用时间: 00: 00: 00.16
11:09:14 SQL>
说明刚才插入的数据已经被删除掉了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17179887/viewspace-660796/
,如需转载,请注明出处,否则将追究法律责任。