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

总结

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

相关推荐
希冀1239 分钟前
【操作系统】1.2操作系统的发展与分类
后端
GoppViper38 分钟前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people2 小时前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
罗政7 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
拾光师9 小时前
spring获取当前request
java·后端·spring
Java小白笔记10 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
JOJO___12 小时前
Spring IoC 配置类 总结
java·后端·spring·java-ee
白总Server13 小时前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php
Lingbug14 小时前
.Net日志组件之NLog的使用和配置
后端·c#·.net·.netcore