Oracle入门(十四.20)之创建DML触发器:第一部分

一、什么是DML触发器?

DML触发器是执行SQL DML语句(INSERT,UPDATE或DELETE)时自动触发(执行)的触发器。 您可以通过两种方法对DML触发器进行分类:
•执行时间:BEFORE,AFTER或INSTEAD触发DML语句。
•它们执行的次数:一次对于整个DML语句(一个语句触发器),或者对于受DML语句影响的每一行一次(一行

触发)。


二、创建DML语句触发器

CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3] ON object_name
trigger_body

•timing:当触发器触发与触发事件有关时。 值在之前,之后或停止。

•event:哪个DML操作导致触发器触发。 值是INSERT,UPDATE [OF列]和DELETE。

•object_name:与触发器关联的表或视图。

•trigger_body:由触发器执行的操作在匿名块中定义。

(1)语句触发时序

触发器何时应该触发?
•BEFORE:在表格上的触发DML事件之前执行触发器主体。
•AFTER:在表格上触发DML事件后执行触发器主体。
•INSTEAD OF:在视图上执行触发器主体而不是触发DML事件。
编程要求将决定使用哪一个。

(2)触发时间和事件示例

第一个触发器在员工的工资更新之前立即执行:

CREATE OR REPLACE TRIGGER sal_upd_trigg
BEFORE UPDATE OF salary ON employees
BEGIN ... END;
员工被删除后立即执行第二个触发器:
CREATE OR REPLACE TRIGGER emp_del_trigg
AFTER DELETE ON employees
BEGIN ... END;

可以限制UPDATE触发器更新特定列或列:

CREATE OR REPLACE TRIGGER sal_upd_trigg
BEFORE UPDATE OF salary, commission_pct ON employees
BEGIN ... END;

触发器可能有多个触发事件:

CREATE OR REPLACE TRIGGER emp_del_trigg
AFTER INSERT OR DELETE OR UPDATE ON employees
BEGIN ... END;


三、怎样使触发器触发?

(1)声明触发器:
•触发语句的每次执行仅触发一次
•是DML触发器的默认类型
•即使没有行受到影响,也会触发一次
CREATE OR REPLACE TRIGGER log_emp_changes
AFTER UPDATE ON employees BEGIN
INSERT INTO log_emp_table (who, when)
 VALUES (USER, SYSDATE);
END;

现在执行UPDATE语句:

UPDATE employees SET ... WHERE ...;
触发器触发多少次,如果UPDATE语句修改三行? 十行? 一行?没有行?

(2)触发器何时触发

此幻灯片显示与事件INSERT INTO departments关联的语句触发器的触发顺序:
INSERT INTO departments
 (department_id,department_name, location_id)
VALUES (400, 'CONSULTING', 2500);


四、触发器触发序列

即使触发的DML语句影响许多行,语句触发器也只触发一次:

UPDATE employees
 SET salary = salary * 1.1
 WHERE department_id = 50;

(1)DML语句触发器示例1

每当一行或多行成功插入到EMPLOYEES中时,此语句触发器就会自动将一行插入到日志记录表中。


(2)DML语句触发器示例2

每次在DEPARTMENTS表上成功执行DML操作时,此语句触发器都会自动向日志记录表中插入一行。

CREATE OR REPLACE TRIGGER log_dept_changes
AFTER INSERT OR UPDATE OR DELETE ON DEPARTMENTS
BEGIN
INSERT INTO log_dept_table (which_user, when_done)
 VALUES (USER, SYSDATE);
END;
(3)DML语句触发器示例3
这个例子展示了如何使用DML触发器来强制执行复杂的业务规则,这些规则不能被约束强制执行。
希望在正常工作日(星期一至星期五)允许INSERT进入EMPLOYEES表,但在周末(周六和周五)禁止INSERT

星期日)。

如果用户试图在周末期间向EMPLOYEES表中插入一行,则用户将看到错误消息,触发器失败,并且触发语句被回滚。以下显示了此示例所需的触发器代码。


CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT ON employees
BEGIN
IF TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN') THEN
 RAISE_APPLICATION_ERROR(-20500,
 'You may insert into EMPLOYEES'
 ||' table only during business hours');
 END IF;
END;
(4)测试SECURE_EMP
用户尝试在周末插入一行:
INSERT INTO employees (employee_id, last_name,
first_name, email, hire_date, job_id, salary, department_id)
VALUES (300, 'Smith', 'Rob', 'RSMITH', SYSDATE,'IT_PROG', 4500, 60);
ORA-20500: You may insert into EMPLOYEES table only during business
hours.
ORA-06512: at “USVA_TEST_SQL01_T01.SECURE_EMP”, line 4
ORA_04088: error during execution of trigger
‘USVA_TEST_SQL01_T01.SECURE_EMP’
2. VALUES (300, ‘Smith’, ‘Rob’, ‘RSMITH’, SYSDATE, ‘IT_PROG’, 4500,
60);
(5)最后一个例子

该触发器不能成功编译。 为什么不?

CREATE OR REPLACE TRIGGER log_dept_changes
AFTER INSERT OR UPDATE OR DELETE ON DEPARTMENTS
BEGIN
INSERT INTO log_dept_table (which_user, when_done)
 VALUES (USER, SYSDATE);
 COMMIT;
END;

猜你喜欢

转载自blog.csdn.net/moakun/article/details/80535821