PLSQL触发器

1.触发器定义
触发器作为数据库对象之一,并不像函数或是存储过程那样被调用,而是由特定的语句所引起/触发所执行的.
用于做出特殊处理或是提示

2.触发器分类
2.1DML 触发器:又分为表级触发器和行级触发器
2.2视图触发器(代替触发器)
2.3系统触发器

3.触发器属性
3.1状态属性
触发器由于是由于DML语句所引起的对象,拥有两种可定义运行的状态:AFTER/BEFORE
分别表示 该触发语句是在完全执行DML前还是后执行 
同时 UPDATE 和 INSERT INTO 会拥有两种特别的属性
:NEW:=
:OLD:=
这两个参数分别表示对应字段的数值新旧值:即更新前和更新后的值
这两个参数只能用在行级触发器中

3.2事件属性
在DML触发器中,由于被INSERT、UPDATE、DELETE 所引起,分别对应三种布尔类型的数据:INSERTING、UPDATING、DELETING

4.DML触发器运用
4.1表级触发器
--触发的对象是一整张表

--由于触发器没有参数,所以不需要接受,同时需要定义对应触发器的属性特点

CREATE OR REPLACE TRIGGER TRI_DEMO
AFTER/BEFORE INSERT OR UPDATE OR DELETE(三个参数都可以存在,表示哪些类型的DML语句会引起触发器) ON TABLE_NAME
DECLARE

BEGIN
--logic code  
END;

--示例
--为emp表创建触发器
CREATE OR REPLACE TRIGGER TRI_EMP
BEFORE INSERT OR UPDATE OR DELETE ON EMP
DECLARE
BEGIN
  DBMS_OUTPUT.PUT_LINE('执行成功!');
  --我们来看看触发器的属性
--事件属性
  DBMS_OUTPUT.PUT_LINE(B2C(INSERTING));
  DBMS_OUTPUT.PUT_LINE(B2C(UPDATING));
  DBMS_OUTPUT.PUT_LINE(B2C(DELETING));
  --执行DML 触发器成功响应
END;

INSERT INTO EMP(EMPNO) VALUES(1234);


4.2行级触发器

CREATE OR REPLACE TRIGGER TRI_REMP
BEFORE INSERT OR UPDATE OR DELETE ON EMP FOR EACH ROW
DECLARE
BEGIN
  DBMS_OUTPUT.PUT_LINE('执行成功!');
  --我们来看看触发器的属性
--事件属性
  DBMS_OUTPUT.PUT_LINE(B2C(INSERTING));
  DBMS_OUTPUT.PUT_LINE(B2C(UPDATING));
  DBMS_OUTPUT.PUT_LINE(B2C(DELETING));
  --执行DML 触发器成功响应

--触发器状态
IF :OLD.EMPNO IS NULL THEN
  DBMS_OUTPUT.PUT_LINE('OLD IS NULL');
  ELSE 
  DBMS_OUTPUT.PUT_LINE(:OLD.EMPNO);
  END IF;
  DBMS_OUTPUT.PUT_LINE(:NEW.EMPNO);
  END;
 --调用
INSERT INTO EMP(EMPNO) VALUES(1234);


--在行级触发器中 如果触发器被定义为在DML语句完全生效前执行 那么:NEW属性可以去覆盖某些值 但是:OLD永远不会被覆盖
--示例
CREATE OR REPLACE TRIGGER TRI_DEPT
BEFORE INSERT OR UPDATE OR DELETE ON DEPT FOR EACH ROW
DECLARE
BEGIN
  DBMS_OUTPUT.PUT_LINE('执行成功!');
IF :OLD.LOC IS NULL THEN
  DBMS_OUTPUT.PUT_LINE('OLD IS NULL');
  ELSE 
  DBMS_OUTPUT.PUT_LINE(:OLD.LOC);
  END IF;
  :NEW.LOC:='UN';
  END;
 --调用
UPDATE DEPT SET LOC='EXCEPTION';

SELECT * FROM DEPT;--可以看到全部被NEW.LOC覆盖,当定义为AFTER触发器时则无效


5.代替触发器的运用
5.1代替触发器的含义
顾名思义,当满足触发器执行的条件后,不真正执行用户选中的DML语句转而执行触发器中的逻辑代码
称为代替触发器.
代替触发器所建立的载体是视图,故也叫视图触发器

--示例:为EMP建立一个代替触发器,当EMP执行DML语句时输出:权限不足
--首先需要创建一个视图
CREATE VIEW VIEW_EMP AS SELECT * FROM EMP;
--创建代替触发器
CREATE OR REPLACE TRIGGER TRI_IN_EMP
INSTEAD OF INSERT OR UPDATE OR DELETE ON VIEW_EMP --[FOR EACH ROW]可选
DECLARE
BEGIN
    DBMS_OUTPUT.PUT_LINE('你权限不足');
END;
INSERT INTO VIEW_EMP(EMPNO) VALUES(1234);--可以看到事务窗口未相应,并执行了代替触发器
--创建复杂的视图
CREATE VIEW VIEW_E_D AS SELECT EMPNO,ENAME,JOB,DNAME FROM EMP E JOIN DEPT D ON E.DEPTNO=D.DEPTNO;
--创建对应视图的触发器
CREATE OR REPLACE TRIGGER TRI_E_D
INSTEAD OF INSERT  ON VIEW_E_D FOR EACH ROW
BEGIN
      DBMS_OUTPUT.PUT_LINE('权限等级可解锁');
      --INSERT INTO VIEW_E_D(EMPNO,JOB,DNAME) VALUES(2345,'BOSS','UK');--执行失败
      --那就是视图做了表连接,但是没键新表
      INSERT INTO EMP(EMPNO,JOB) VALUES(2223,'BOSS');--成功执行
      
END;

INSERT INTO VIEW_E_D(EMPNO) VALUES(1234);--可以看到事务窗口未相应,并执行了代替触发器


6.实际运用
--创建一张表,字段(id-主键,name-普通字段),
--通过触发器实现ID的自增赋值,不要体现在SQL语句中。
6.1什么是序列 怎么定义 使用?
6.1.1 序列的创建
序列是一个可以设置自增长的数据库对象,常用来让主键自增
DROP SEQUENCE SEQ_TAB;
CREATE SEQUENCE SEQ_TAB
MAXVALUE 100
MINVALUE 1
START WITH 1
INCREMENT BY 1;
6.1.2序列属性
序列在创建后,可以通过SEQUENCE_NAME.NEXTVAL来初始化序列,通过SEQUENCE_NAME.CURRVAL来查看序列当前值
SELECT SEQ_TAB.NEXTVAL FROM DUAL;
SELECT SEQ_TAB.CURRVAL FROM DUAL;

三.问题

1.创建一个用于记录用户问题的触发器:
创建一个dept_log数据表,并在其中定义两个字段(operate_tag varchar2(10),operate_time date),
分别用来存储操作种类(插入,修改,删除)信息和操作日期。然后一个关于dept表的语句级触发器tri_dept,
将用户对 dept 表的操作信息保存到dept_tag表中。
当任何时候从dept表中删除某个部门时,该触发器将从emp表中删除该部门的所有雇员。(该问题转载于CSDN博主「Xiu Yan」)

--操作种类:update、delete、insert ,操作他们的信息和日期
--创建一个建立在DEPT_LOG上的触发器 TRI_DEPT
--功能要求:当执行delete语句时 触发器将删除emp中的所有该部门员工

--首先建一个备份表
SELECT * FROM EMP_BAK;--备份表没有任何约束 可自由操作

CREATE TABLE DEPT_LOG (OPERATE_TAG VARCHAR2(10),OPERATE_TIME DATE);
--创建触发器
CREATE OR REPLACE TRIGGER TRI_DEPT
AFTER INSERT OR UPDATE OR DELETE ON DEPT_BAK FOR EACH ROW
DECLARE

BEGIN
  IF INSERTING THEN
  INSERT INTO DEPT_LOG VALUES('插入数据',SYSDATE);
  ELSIF UPDATING THEN
  INSERT INTO DEPT_LOG VALUES('更新数据',SYSDATE);
  ELSE 
  INSERT INTO DEPT_LOG VALUES('删除数据',SYSDATE);
  END IF;
  DELETE FROM EMP_BAK WHERE DEPTNO=:OLD.DEPTNO;
END;
--调用触发器
DELETE  FROM DEPT_BAK WHERE DEPTNO=10;--可以看到需求都已经实现
--查验
SELECT * FROM DEPT_LOG;
SELECT * FROM EMP_BAK;
SELECT * FROM DEPT_BAK;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值