Oracle触发器分类及使用

例1: 建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。
–创建临时表
CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2;

CREATE OR REPLACE TRIGGER tr_del_emp
BEFORE DELETE --指定触发时机为删除操作前触发
ON scott.emp
FOR EACH ROW --说明创建的是行级触发器
BEGIN --将修改前数据插入到日志记录表del_emp,以供监督使用。
INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate )
VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate );
END;
–测试触发器
DELETE emp WHERE empno=7788;
DROP TABLE emp_his;
DROP TRIGGER del_emp;
在Oracle中,触发器是一种特殊的存储过程,它在发生某种数据库事件时由Oracle系统自动触发。触发器通常用于加强数据的完整性约束和业务规则等,对于表来说,触发器可以实现比CHECK约束更为复杂的约束。
概念:在Oracle中,触发器是一种特殊的存储过程,它在发生某种数据库事件时由Oracle系统自动触发发器,通常用于加强数据的完整性约束和业务规则等。
触发器与存储过程的区别在于:存储过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的,而是由一个事件来启动运行。即触发器是当某个时间发生时自动地隐式运行。
功能:
1、允许/限制对表的修改
2、自动生成派生列,比如自增字段
3、强制数据一致性
4、提供审计和日志记录
5、防止无效的事务处理
6、启用复杂的业务逻辑
建立对象:

  1. 触发事件:引起触发器被触发的事件。 例如:DML语句(INSERT, UPDATE, DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登录或退出数据库)。
  2. 触发时间:即该TRIGGER是在触发事件发生之前(BEFORE)还是之后(AFTER)触发。
  3. 触发对象:包括表、视图、模式、数据库。只有在这些对象上发生了符合触发条件的触发事件,才会执行触发操作。
  4. 触发条件:由WHEN子句指定一个逻辑表达式。只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作。
  5. 触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。
    触发次序:
    执行 BEFORE行级触发器
    执行 DML语句
    执行 AFTER行级触发器

触发器语法格式
create [or replace] trigger 触发器名 触发时间 触发事件

[on 表 | on schema ]

[referencing new as 别名 old as 别名]

[for each row]

pl/sql 语句

触发器名:触发器对象的名称。由于触发器是数据库自动执行 的,因此该名称只是一个名称,没有实质的用途。

触发时间:指明触发器何时执行,该值可取:

before—表示在数据库动作之前触发器执行;

after—表示在数据库动作之后出发器执行。

触发事件:指明哪些数据库动作会触发此触发器:

insert:数据库插入会触发此触发器;

update:数据库修改会触发此触发器;

delete:数据库删除会触发此触发器。

表 名:数据库触发器所在的表。
on schema : 可以通过事件引发ora_sysevent 获取当前操作

for each row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次。
别名 :用于定义接收参数
例1: 建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。
–创建临时表
CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2;

CREATE OR REPLACE TRIGGER tr_del_emp
BEFORE DELETE --指定触发时机为删除操作前触发
ON scott.emp //在 scott.emp表中建立
FOR EACH ROW --说明创建的是行级触发器
BEGIN --将修改前数据插入到日志记录表del_emp,以供监督使用。
INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate ) //表,列
VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate ); //名
END;
–测试触发器
DELETE emp WHERE empno=7788;
DROP TABLE emp_his;
DROP TRIGGER del_emp;
替代触发器
INSTEAD OF触发器又称为替代触发器,用于执行一个替代操作来代替触发事件的操作。例如:针对INSERT事件的INSTEAD OF触发器,它由INSERT语句触发,当出现INSERT语句时,该语句不会被执行,而是执行INSTEAD OF触发器中定义的语句。
创建INSTEAD OF触发器需要注意以下几点:
在这里插入图片描述
例:当需要针对视图创建触发器来处理业务逻辑,或数据流程时, 可以用替代触发器来实现对视图相关表的操作.
代码演示:
create table user_info ( id number,name varchar2(200));
insert into user_info values(1,‘DINYA’);
create table skill( id number,skill varchar2(300),user_id number);
insert into skill values(1,‘打字’,1);
create or replace view user_skills as select a.id ,a.name,b.skill from user_info a,skill b where a.id=b.user_id;
select * from user_skills
update user_skills t set t.skill=‘上网’

create or replace trigger user_skills_update
instead of update on user_skills
for each row
begin
update skill set skill=:new.skill where user_id=:old.id;
end ;
–测试
update user_skills t set t.skill=‘上网’ where t.id=1;
系统事件触发器:系统事件触发器在发生如数据库启动或者关闭等系统事件时触发,包括数据库服务器的启动或关闭,用户的登录与退出、数据库服务错误等。
例5:创建登录、退出触发器
代码演示:
CREATE TABLE log_event
(user_name VARCHAR2(10),
address VARCHAR2(20),
logon_date timestamp,
logoff_date timestamp);
–创建登录触发器
CREATE OR REPLACE TRIGGER tr_logon
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logon_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logon;
创建退出触发器
代码演示:
CREATE OR REPLACE TRIGGER tr_logoff
BEFORE LOGOFF ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logoff_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logoff;
DDL触发器:DDL触发器由DDL语句触发,例如:CREATE、ALTER和DROP语句。DDL触发器同样可以分为BEFORE触发器与AFTER触发器
代码演示:
create table ddl_log (operation varchar2(30),obj_owner varchar2(30),object_name varchar2(30),sql_text varchar2(64),attempt_by varchar2(30),attempt_dt date);

create or replace procedure log_proc(ose ddl_log.operation%type,
odoo ddl_log.obj_owner%type,
odon ddl_log.object_name%type) is
begin
insert into ddl_log
select ora_sysevent,
ora_dict_obj_owner,
ora_dict_obj_name,
‘not allowed’,
user,
sysdate
from dual;
end log_proc;

create or replace trigger save_our_db
before drop or truncate on schema
declare
oper ddl_log.operation%TYPE;
begin
–select ora_sysevent into oper from dual;
log_proc(ora_sysevent, ora_dict_obj_owner, ora_dict_obj_name);
end save_our_db;

–测试
drop table emp_his
触发器的应用
Oracle触发器一般应用在以下方面:
1 确保数据库的安全性
可以基于时间限制用户的操作,例如不允许下班后和节假日修改数据库数据。
可以基于数据库中的数据限制用户的操作,例如不允许价格的升幅一次超过10%。
2 提供复杂的审计功能
审计用户操作数据库的语句。
把用户对数据库的更新写入审计表。
3 维护不同数据库之间同步表
在不同的数据库之间可以利用快照(oracle数据库的快照是一个表,它包含有对一个本地或远程数据库上一个或多个表或视图的查询的结果。也就是说快照根本的原理就是将本地或远程数据库上的一个查询结果保存在一个表中)来实现数据的复制,但有些系统要求两个数据库数据实时同步,就必须利用触发器从一个数据库中向另一个数据库复制数据。
编写触发器注意事项
1、触发器不接受参数。
2、一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。
3、在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。
4、触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。
5、触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回退了。
6、在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。

猜你喜欢

转载自blog.csdn.net/weixin_40645193/article/details/107598435