oracle触发器

触发器(TRIGGER)是一类特殊的存储过程,它可以对表进行插入、修改、删除时被激发激活而执行的数据库对象

触发器可以分为前触发器、后触发器、行触发器

所谓行触发器是指被定义的行数据发生变化时,二执行的数据库对象,被称为行触发器

创建触发器:

CREATE [OR REPLACE] TRIGGER trigger_name
BEFORE|AFTER INSERT|UPDATE|DELETE 在激活动作之前(后)创建触发器
ON table_name
[FOR EACH ROW]
[WHEN condition_expression]
PL/SQL;

  说明:

   OR REPLACE:替换,但不是万能替换,只有这个触发器名已经存在,并且时同一个表的触发器才会替换;

         BEFORE|AFTER:触发器的激活时机;

         INSERT|UPDATE|DELETE:触发器的激活动作;

         ON table_name:触发器的作用表;

         FOR EACH ROW:创建行触发器; 

         WHEN condition_expression:行触发器的激活条件,但要注意,行触发器可以没有激活条件,但是有激活条件必有行触发器;

         PL/SQL:触发器的主体部分;

  在触发器中如果需要定义变量需要有 DECLARE 关键字,因为存储过程不需要

  【例】创建temp(ID,NAME),向temp中添加记录前,将temp表中所有记录删除

  

CREATE TABLE temp                        
 (                                   
ID NUMBER(3),
NAME VARCHAR2(10)
)
INSERT INTO temp VALUES(1,'a');
INSERT INTO temp VALUES(2,'b');
INSERT INTO temp VALUES(4,'d');
	 
CREATE TRIGGER tr1
BEFORE INSERT
ON temp
BEGIN
DELETE FROM temp;
 END;

删除触发器:

语法:

DROP TRIGGER trigger_name;

触发器实现原理:

oracle 中有两个特殊变量:NEW 和 OLD 他们的数据类型时%ROWTYPE:

NEW   INSERT /UPDATE

OLD   DELETE /UPDATE

在触发器说明部分可以直接使用 NEW 或 OLD 变量,但在主体部分中使用这两个变量一定要加“:”,也就是:':new'和':old'

解说:当激活动作时 INSERT 或 UPDATE 时, NEW 变量中始终存放新添加或修改后的那条记录;当激活动作是 UPDATE 或 DELETE 时,OLD 变量中始终存放删除后或修改前的那条记录,这就是触发器的实现原理

例:创建score表,字段有id和grade(成绩),当向这个表中添加记录后,要求显示新添加学生的编号  

CREATE TABLE score
(
	ID NUMBER(3),
	grade NUMBER(4,1)
)

CREATE TRIGGER tr1
AFTER INSERT
ON score
FOR EACH ROW
BEGIN
	dbms_output.put_line('新添加的学生编号是:':new.id);
END;

INSERT INTO score VALUES(10,87);

例:当销售一种商品时,要求这种商品的库存量做出相应的减少

CREATE TRIGGER tr1
AFTER INSERT
ON shop_xs
FOR EACH ROW
BEGIN
	UPDATE shop_jb SET stock=stock-:new.quantity WHERE ID=:new.id;
	dbms_output.put_line(:new.id||'号商品的库存量被修改');
END;

INSERT INTO shop_xs VALUES(10,1000,9,SYSDATE,009);

例:

创建score表,包含两个字段,分别为id和grade,向表中添加5条记录

创建触发器,实现当修改这个表中学生成绩字段后,如果该学生成绩及格要求显示:

那个学生的成绩被修改

修改前学生的成绩是多少

修改后学生的成绩是多少

该学生的成绩是提高了还是后退了

前进或后退了多少分  

CREATE TRIGGER tr1
AFTER UPDATE
ON score
FOR EACH ROW
  WHEN(new.grade>=60)
		DECLARE
			v_gradiff INT :=:new.grade-:old.grade;
		BEGIN
			dbms_output.put_line(:new.id||'号学生成绩被修改');
			dbms_output.put_line('修改前学生的成绩为:'||:old.grade||'分');
			dbms_output.put_line('修改后学生的成绩为:'||:new.grade||'分');
			IF v_gradiff>0 THEN
				dbms_output.put_line('该学生成绩提高了'||v_gradiff||'分');
			ELSIF v_gradiff<0 THEN 
				dbms_output.put_line('该学生后退了'||ABS(v_gradiff)||'分');
			ELSE 
				dbms_output.put_line('你很厉害啊,成绩保持得非常号...');
			END IF;
		END;

  

原文地址:https://www.cnblogs.com/xiaotudou-datudou/p/4874940.html