返回介绍

PL/SQL 触发器 - PL/SQL 教程

发布于 2025-02-22 13:46:47 字数 3478 浏览 0 评论 0 收藏 0

触发器是存储程序,它会自动执行或发射当一些事件发生。触发器,事实上,写入响应于以下任一事件将被执行:

  • 数据库操作(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 |
+----+----------+-----+-----------+----------+

下面的程序创建了 customers 表中,将触发 INSERT 或 UPDATE 或 DELETE 在 Customers 表进行操作的行级触发。触发器将显示工资的旧值和新值之间的差额:

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,这将会触发每当一个记录将使用在表上删除操作被删除。

触发一个触发器

让我们在 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:

因为这是一个新的记录,因此基本工资不可用及以上的结果来为空(null)。现在,让我们对 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文