触发器是存储程序,它会自动执行或发射当一些事件发生。触发器,事实上,写入响应于以下任一事件将被执行:
数据库操作(DML)语句(DELETE,INSERT,UPDATE或)
数据库定义(DDL)语句(CREATE,ALTER或DROP)
数据库操作(SERVERERROR,登录,注销,启动或关机)
触发器可以在表,视图,模式或数据库与该事件相关联上定义
触发器可以用于以下目的写:
自动生成一些派生列值
实施参照完整性
事件日志和对表的访问存储信息
审计
表的同步复制
实行安全许可
防止非法交易
创建触发器的语法:
CREATE [OR REPLACE ] TRIGGER trigger_name |
{BEFORE | AFTER | INSTEAD OF } |
{INSERT [OR] | UPDATE [OR] | DELETE} |
[OF col_name] |
ON table_name |
[REFERENCING OLD AS o NEW AS n] |
[FOR EACH ROW] |
WHEN (condition) |
DECLARE |
Declaration-statements |
BEGIN |
Executable-statements |
EXCEPTION |
Exception-handling-statements |
END; |
那么
CREATE [OR REPLACE] TRIGGER trigger_name: 创建或替换现有的触发器:trigger_name
{BEFORE | AFTER | INSTEAD OF} : 指定当触发将被执行。在INSTEAD OF子句用于在视图中创建触发器
{INSERT [OR] | UPDATE [OR] | DELETE}: 指定DML操作
[OF col_name]: 指定将被更新的列名
[ON table_name]: 指定触发器相关联的表的名称
[REFERENCING OLD AS o NEW AS n]: 可以参考新旧值的各种DML语句,如INSERT,UPDATE和DELETE
[FOR EACH ROW]: 指定的行级触发器,即触发器将每一行受到影响执行。否则,当执行SQL语句,这被称为表级触发器触发将执行一次
WHEN (condition): 触发器将触发的条件。此子句仅适用于行级触发器有效
首先,将使用我们已经创建,并在前面的章节中使用的CUSTOMERS表:
Select * from customers; |
+----+----------+-----+-----------+----------+ |
| ID | NAME | AGE | ADDRESS | SALARY | |
+----+----------+-----+-----------+----------+ |
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 | |
| 2 | Khilan | 25 | Delhi | 1500.00 | |
| 3 | kaushik | 23 | Kota | 2000.00 | |
| 4 | Chaitali | 25 | Mumbai | 6500.00 | |
| 5 | Hardik | 27 | Bhopal | 8500.00 | |
| 6 | Komal | 22 | MP | 4500.00 | |
+----+----------+-----+-----------+----------+ |
CREATE OR REPLACE TRIGGER display_salary_changes |
BEFORE DELETE OR INSERT OR UPDATE ON customers |
FOR EACH ROW |
WHEN (NEW.ID > 0) |
DECLARE |
sal_diff number; |
BEGIN |
sal_diff := :NEW.salary - :OLD.salary; |
dbms_output.put_line('Old salary: ' || :OLD.salary); |
dbms_output.put_line('New salary: ' || :NEW.salary); |
dbms_output.put_line('Salary difference: ' || sal_diff); |
END; |
/ |
Trigger created.
这里以下两点是重要的,应小心注意:
OLD和NEW引用是不可用于表级触发器,而不可以使用它们的创纪录级别的触发器。
如果想查询表中相同的触发,那么应用应该使用AFTER关键字,因为触发器可以查询该表,或再次改变它最初的变化仅适用后的表是回到一致的状态。
上述触发已经写在这样一种方式,它会在任何DELETE、INSERT或UPDATE操作在表上之前执行,但可以夺触发器上编写一个或多个操作,例如BEFORE DELETE,这将会触发每当一个记录将使用在表上删除操作被删除。
让我们在CUSTOMERS表执行某些DML操作。这里有一个INSERT语句,这将在表中创建一个新的记录:
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) |
VALUES (7, 'Kriti', 22, 'HP', 7500.00 ); |
Old salary: New salary: 7500 Salary difference:因为这是一个新的记录,因此基本工资不可用及以上的结果来为空(null)。现在,让我们对CUSTOMERS表进行多一个DML操作。这里有一个UPDATE语句,该语句将更新表中现有的记录:
UPDATE customers |
SET salary = salary + 500 |
WHERE id = 2; |
Old salary: 1500 New salary: 2000 Salary difference: 500