- PL/SQL 教程
- PL/SQL - 主页
- PL/SQL - 概述
- PL/SQL - 环境
- PL/SQL - 基本语法
- PL/SQL - 数据类型
- PL/SQL - 变量
- PL/SQL - 常量和文字
- PL/SQL - 运算符
- PL/SQL - 条件
- PL/SQL - 循环
- PL/SQL - 字符串
- PL/SQL - 数组
- PL/SQL - 过程
- PL/SQL - 函数
- PL/SQL - 游标
- PL/SQL - 记录
- PL/SQL - 异常
- PL/SQL - 触发器
- PL/SQL - 包
- PL/SQL - 集合
- PL/SQL - 事务
- PL/SQL - 日期和时间
- PL/SQL - DBMS 输出
- PL/SQL - 面向对象
- PL/SQL 有用资源
- PL/SQL - 问题与解答
- PL/SQL - 快速指南
- PL/SQL - 有用的资源
- PL/SQL - 讨论
PL/SQL - 触发器
在本章中,我们将讨论 PL/SQL 中的触发器。触发器是存储的程序,当某些事件发生时自动执行或触发。事实上,触发器是为了响应以下任何事件而编写的:
数据库操作 (DML)语句(DELETE、INSERT 或 UPDATE)
数据库定义 (DDL)语句(CREATE、ALTER 或 DROP)。
数据库操作(SERVERERROR、LOGON、LOGOFF、STARTUP 或 SHUTDOWN)。
可以在与事件关联的表、视图、模式或数据库上定义触发器。
触发器的好处
可以出于以下目的编写触发器 -
- 自动生成一些派生列值
- 强制引用完整性
- 事件记录和存储有关表访问的信息
- 审计
- 表的同步复制
- 实施安全授权
- 防止无效交易
创建触发器
创建触发器的语法是 -
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 - 创建现有触发器或使用触发器名称替换现有触发器。
{之前 | 之后 | INSTEAD OF} - 这指定何时执行触发器。INSTEAD OF 子句用于在视图上创建触发器。
{插入[或] | 更新[或] | DELETE} - 这指定 DML 操作。
[OF col_name] - 这指定将更新的列名。
[ON table_name] - 这指定与触发器关联的表的名称。
[REFERENCING OLD AS o NEW AS n] - 这允许您引用各种 DML 语句的新值和旧值,例如 INSERT、UPDATE 和 DELETE。
[FOR EACH ROW] - 这指定行级触发器,即将为受影响的每一行执行触发器。否则触发器在执行SQL语句时只执行一次,称为表级触发器。
WHEN(条件)- 这为触发触发器的行提供了一个条件。该子句仅对行级触发器有效。
例子
首先,我们将使用我们在前面的章节中创建和使用的 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 | +----+----------+-----+-----------+----------+
以下程序为客户表创建一个行级触发器,该触发器将在对 CUSTOMERS 表执行 INSERT、UPDATE 或 DELETE 操作时触发。此触发器将显示旧值和新值之间的工资差异 -
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; /
当上面的代码在 SQL 提示符下执行时,会产生以下结果 -
Trigger created.
这里需要考虑以下几点 -
OLD 和 NEW 引用不可用于表级触发器,但您可以将它们用于记录级触发器。
如果要在同一个触发器中查询表,那么应该使用 AFTER 关键字,因为只有在应用初始更改并且表恢复到一致状态后,触发器才能查询表或再次更改表。
上面的触发器是以这样的方式编写的:它将在表上的任何 DELETE、INSERT 或 UPDATE 操作之前触发,但是您可以在单个或多个操作上编写触发器,例如 BEFORE DELETE,只要有一条记录就会触发将使用表上的 DELETE 操作来删除。
触发触发器
让我们对 CUSTOMERS 表执行一些 DML 操作。这是一个 INSERT 语句,它将在表中创建一条新记录 -
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES (7, 'Kriti', 22, 'HP', 7500.00 );
当在 CUSTOMERS 表中创建记录时,上面的创建触发器display_salary_changes将被触发,并将显示以下结果 -
Old salary: New salary: 7500 Salary difference:
由于这是新记录,因此无法获得旧工资,因此上述结果为空。现在让我们对 CUSTOMERS 表再执行一项 DML 操作。UPDATE 语句将更新表中的现有记录 -
UPDATE customers SET salary = salary + 500 WHERE id = 2;
当 CUSTOMERS 表中的记录更新时,上面的创建触发器display_salary_changes将被触发,并将显示以下结果 -
Old salary: 1500 New salary: 2000 Salary difference: 500