Oracle(39)什么是触发器(Trigger)?如何创建触发器?

触发器(Trigger)是数据库中一种特殊的存储过程,它在特定的数据库事件(如INSERT、UPDATE或DELETE操作)发生时自动执行。触发器可以用于实现复杂的数据完整性约束、审计、日志记录和自动化任务等功能。

触发器的类型

触发器按触发事件和触发时间可以分为以下几种类型:

  1. 按触发事件

    • INSERT触发器:在插入数据时触发。
    • UPDATE触发器:在更新数据时触发。
    • DELETE触发器:在删除数据时触发。
  2. 按触发时间

    • BEFORE触发器:在事件发生之前触发。
    • AFTER触发器:在事件发生之后触发。

创建触发器的步骤

  1. 定义触发器的名称
  2. 指定触发事件(INSERT、UPDATE、DELETE)
  3. 指定触发时间(BEFORE、AFTER)
  4. 指定触发的表
  5. 编写触发器的执行逻辑

代码示例

下面的示例展示了如何创建一个触发器,该触发器在 employees 表插入数据之前检查薪水是否大于零,如果不是则抛出异常。同时,我们还展示了如何创建一个在 employees 表更新数据之后记录修改信息的触发器。

1. 创建表和插入示例数据

首先,创建一个测试表 employees

sql 复制代码
CREATE TABLE employees (
    employee_id NUMBER PRIMARY KEY,
    first_name VARCHAR2(50),
    last_name VARCHAR2(50),
    salary NUMBER
);

-- 创建日志表,用于记录更新操作
CREATE TABLE employees_log (
    log_id NUMBER PRIMARY KEY,
    employee_id NUMBER,
    old_salary NUMBER,
    new_salary NUMBER,
    update_date DATE
);

COMMIT;

2. 创建 BEFORE INSERT 触发器

这个触发器在向 employees 表插入数据之前检查薪水是否大于零,如果不是则抛出异常。

sql 复制代码
CREATE OR REPLACE TRIGGER before_insert_employee
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
    IF :NEW.salary <= 0 THEN
        RAISE_APPLICATION_ERROR(-20001, 'Salary must be greater than zero');
    END IF;
END;
/

3. 创建 AFTER UPDATE 触发器

这个触发器在更新 employees 表之后记录修改信息到 employees_log 表。

sql 复制代码
CREATE OR REPLACE TRIGGER after_update_employee
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
    INSERT INTO employees_log (log_id, employee_id, old_salary, new_salary, update_date)
    VALUES (employees_log_seq.NEXTVAL, :OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
/

4. 测试触发器

测试 BEFORE INSERT 触发器

尝试插入一条薪水小于等于零的记录,应该会触发异常。

sql 复制代码
BEGIN
    INSERT INTO employees (employee_id, first_name, last_name, salary)
    VALUES (1, 'John', 'Doe', -5000);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

输出结果应该是:

makefile 复制代码
ORA-20001: Salary must be greater than zero
测试 AFTER UPDATE 触发器

更新一条记录并查看日志表。

sql 复制代码
-- 插入一条有效记录
INSERT INTO employees (employee_id, first_name, last_name, salary)
VALUES (1, 'John', 'Doe', 5000);

-- 更新记录
UPDATE employees
SET salary = 6000
WHERE employee_id = 1;

-- 查看日志表
SELECT * FROM employees_log;

输出结果应该是:

yaml 复制代码
LOG_ID | EMPLOYEE_ID | OLD_SALARY | NEW_SALARY | UPDATE_DATE
-------|-------------|------------|------------|-------------
1      | 1           | 5000       | 6000       | <更新日期>

触发器的注意事项

  1. 性能影响:触发器会在每次触发事件发生时执行,如果触发器逻辑复杂或触发频率高,可能会影响数据库性能。
  2. 调试困难:触发器在后台自动执行,调试和排查问题可能比较困难。
  3. 递归调用:避免触发器之间的递归调用,可能导致死循环。

总结

触发器是数据库中实现自动化操作和数据完整性约束的重要工具。通过定义触发事件和触发时间,可以在特定的数据库操作发生时自动执行预定义的逻辑。合理使用触发器可以简化代码、增强数据一致性,但也需要注意性能影响和调试困难等问题。在实际开发中,结合业务需求和性能考虑,选择合适的触发器策略。

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
2401_857610034 小时前
多维视角下的知识管理:Spring Boot应用
java·spring boot·后端
代码小鑫4 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计
颜淡慕潇6 小时前
【K8S问题系列 | 9】如何监控集群CPU使用率并设置告警?
后端·云原生·容器·kubernetes·问题解决
独泪了无痕6 小时前
WebStorm 如何调试 Vue 项目
后端·webstorm
怒放吧德德7 小时前
JUC从实战到源码:JMM总得认识一下吧
java·jvm·后端
代码小鑫8 小时前
A025-基于SpringBoot的售楼管理系统的设计与实现
java·开发语言·spring boot·后端·毕业设计
前端SkyRain8 小时前
后端SpringBoot学习项目-项目基础搭建
spring boot·后端·学习
梦想画家8 小时前
理解Rust 生命周期、所有权和借用机制
开发语言·后端·rust
编程乐趣8 小时前
推荐一个.NetCore开源的CMS项目,功能强大、扩展性强、支持插件的系统!
后端