ITPub博客

首页 > 数据库 > Oracle > 数据库开发---常用对象-触发器

数据库开发---常用对象-触发器

原创 Oracle 作者:lff1530983327 时间:2015-01-12 17:23:41 0 删除 编辑

 

---触发器

触发器在数据库里以独立的对象存储

触发器是由一个事件来启动运行

触发器常用来完成由数据库的完整性约束难以完成的复杂业务规则的约束,或用来监视对数据库的各种操作,实现审计的功能。

---触发器分类

1. DML触发器

2.替代触发器

3.系统触发器

---另外一种分法:

语句级(STATEMENT)触发器

行级(ROW)触发器

---另外一种分法:

before

after

------行级触发器专用

:NEW 修饰符访问操作完成后列的值

:OLD 修饰符访问操作完成前列的值

 

:old.deptno 删除之前的数据

:new.deptno 删除之后的数据

--1. 替代(INSTEAD OF)触发器----只能应用在行级上面,无论有没有 for each row

只能用在视图上

CREATE OR REPLACE VIEW v_emp AS

SELECT deptno, count(*) total_emp, sum(sal) total_sal

FROM emp

GROUP BY deptno;---简单视图和原表中的数据是一对一的

 

 

select * from  v_emp;

 

rollback

delete from v_emp where deptno=10;-----复杂视图不能做变更,使用替代触发器

 

CREATE OR REPLACE TRIGGER tr_vemp_del

  INSTEAD OF DELETE ON v_emp

  FOR EACH ROW

BEGIN

  DELETE FROM emp WHERE deptno = :old.deptno;

END tr_vemp_del;

/

DELETE FROM v_emp WHERE deptno=10;

--2.DML触发器

---语句级触发器

CREATE OR REPLACE TRIGGER tr_dept_time

  BEFORE INSERT OR DELETE OR UPDATE ON dept

BEGIN

  IF (TO_CHAR(sysdate, 'DAY') IN ('星期六', '星期日')) OR

     (TO_CHAR(sysdate, 'HH24:MI') NOT BETWEEN '08:00' AND '18:00') THEN

    RAISE_APPLICATION_ERROR(-20001, '非上班时间,不能修改dept表');

  END IF;

END;

/

 

 delete from dept where deptno=10;

 --------------------------------------------------------------

 ----行级触发器

CREATE OR REPLACE TRIGGER tr_emp_sal_comm

  BEFORE UPDATE OF sal, comm OR DELETE ON scott.emp

  FOR EACH ROW

  WHEN (old.deptno = 10)

BEGIN

  CASE

    WHEN UPDATING('sal') THEN

      IF :NEW.sal < :old.sal THEN

        RAISE_APPLICATION_ERROR(-20001, '部门10的人员的工资不能降');

      END IF;

    WHEN UPDATING('comm') THEN

      IF :NEW.comm < :old.comm THEN

        RAISE_APPLICATION_ERROR(-20002, '部门10的人员的奖金不能降');

      END IF;

    WHEN DELETING THEN

      RAISE_APPLICATION_ERROR(-20003, '不能删除部门10的人员记录');

  END CASE;

END;

select * from emp;

UPDATE emp SET sal = 2000 WHERE empno = 7839;

UPDATE emp SET sal = 2    WHERE empno = 7788;

 

---INSTEAD OF触发器需要注意以下几点:

1.只能被创建在视图上,并且该视图没有指定WITH CHECK OPTION选项。

2.不能指定BEFORE 或 AFTER选项。

3.FOR EACH ROW子句是可选的,即INSTEAD OF触发器只能在行级上触发、或只能是行级触发器,没有必要指定。---为了可读性更好,可以加上

-----3. 系统事件触发器

CREATE TABLE ddl_event

(crt_date timestamp PRIMARY KEY,

 event_name VARCHAR2(20),

 user_name VARCHAR2(10),

 obj_type VARCHAR2(20),

 obj_name VARCHAR2(20));

 

CREATE OR REPLACE TRIGGER tr_ddl

  AFTER DDL ON SCHEMA

BEGIN

  INSERT INTO ddl_event

  VALUES

    (systimestamp,

     ora_sysevent,

     ora_login_user,

     ora_dict_obj_type,

     ora_dict_obj_name);

END tr_ddl;

/

 create table tt(id number);

 

 select * from ddl_event;

 SELECT * FROM log_event;

 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_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_nologon

  BEFORE LOGOFF ON DATABASE

BEGIN

  INSERT INTO log_event

    (user_name, address, logon_date)

  VALUES

    (ora_login_user, ora_client_ip_address, systimestamp);

END tr_nologon;

 

 

 

重新编译触发器

ALTER TRIGGER [schema.] trigger_name COMPILE;

DROP TRIGGER trigger_name;

禁用或启用触发器:

ALTER TIGGER trigger_name [DISABLE | ENABLE ];

DISABLE  失效

ENABLE 生效

ALTER TABLE [schema.]table_name {ENABLE|DISABLE} ALL TRIGGERS;

 

ALTER TABLE emp DISABLE ALL TRIGGERS;

 

 

SELECT TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT,

 TABLE_OWNER, BASE_OBJECT_TYPE, REFERENCING_NAMES,

 STATUS, ACTION_TYPE

FROM user_triggers;

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30018455/viewspace-1399309/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-11-12

  • 博文量
    72
  • 访问量
    49744