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

总结

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

相关推荐
IguoChan2 小时前
4. d2l — 模型选择、欠拟合和过拟合
后端
shepherd1262 小时前
一次把 Spring MVC 文件上传参数“查没了”的排查:multipart、Filter 与 request body 的连环坑
java·后端·spring·mvc
贺国亚2 小时前
Prompt-Injection攻防与OWASP-LLM
后端
卷无止境3 小时前
《Deep Analysis with Polars》进阶分析技巧——深入解读
后端·python
Csvn4 小时前
Python 开发技巧 · logging 最佳实践 —— 告别 print,搭建工程级日志系统
后端·python
智码看视界4 小时前
Day19 Spring Boot启动优化:启动时间从8秒降到2秒
java·spring boot·后端·启动优化
IT_陈寒4 小时前
React中useEffect的依赖项把我坑惨了
前端·人工智能·后端
SQL-First布道者5 小时前
Spring JDBC Ultra 十边型战士
java·spring boot·后端·mysql·spring·mybatis
Dovis(誓平步青云)5 小时前
《精讲Spring Boot后端跑另一个端口:如何解决暴露服务器问题》
服务器·人工智能·spring boot·后端·生成对抗网络
进击的程序猿~5 小时前
Go Slice源码深度解析指南
开发语言·后端·golang