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. 递归调用:避免触发器之间的递归调用,可能导致死循环。

总结

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

相关推荐
追逐时光者2 小时前
精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具
后端·.net
TF男孩2 小时前
ARQ:一款低成本的消息队列,实现每秒万级吞吐
后端·python·消息队列
AAA修煤气灶刘哥3 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥3 小时前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
你的人类朋友3 小时前
什么是API签名?
前端·后端·安全
昵称为空C5 小时前
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
spring boot·后端
架构师沉默6 小时前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
RoyLin6 小时前
TypeScript设计模式:适配器模式
前端·后端·node.js
该用户已不存在7 小时前
Mojo vs Python vs Rust: 2025年搞AI,该学哪个?
后端·python·rust
Moonbit7 小时前
MoonBit 正式加入 WebAssembly Component Model 官方文档 !
前端·后端·编程语言