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

总结

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

相关推荐
经典小熊8 分钟前
接手同事代码1小时后,我发现了这个隐藏的return...
后端
编码忘我8 分钟前
java之线程池
java·后端·面试
Carsene14 分钟前
🎉 AutoScan v1.1.0 发布 - 通配符包扫描、排除过滤、自定义注解三大新特性
spring boot·后端
loserwang14 分钟前
Fluss#1386: 从日志恢复中的 OutOfOrder 来看 LEO、HW 与 Checkpoint 的区别
java·后端
PaytonD15 分钟前
基于 GPUI 实现 WebScoket 服务端之服务篇
后端·rust
用户83562907805121 分钟前
使用 Python 精准控制 Word 段落格式
后端·python
StackNoOverflow29 分钟前
Spring Boot 整合 MyBatis + 自动配置原理详解
spring boot·后端·mybatis
zdl6861 小时前
SpringBoot Test详解
spring boot·后端·log4j
小陈工1 小时前
Python后端实战:GraphQL高级应用与性能优化全解析
开发语言·人工智能·后端·python·性能优化·开源·graphql
运维行者_1 小时前
Applications Manager 中的 Azure 监控
运维·服务器·网络·数据库·后端·python·flask