CodeGym /课程 /SQL SELF /创建一个简单的触发器来更新数据:AFTER INSERT

创建一个简单的触发器来更新数据:AFTER INSERT

SQL SELF
第 57 级 , 课程 3
可用

假设我们有一张表,专门存学生的数据。在这张表里,我们想每次加新学生的时候,自动更新last_modified(记录最后修改时间)这个字段。这个字段很重要,用来追踪数据变化和管理数据。

流程大概是这样的:

  1. 每当表里加一条新记录,last_modified字段会自动变成当前的日期和时间。
  2. 我们会用AFTER INSERT触发器,这个触发器会在数据插入成功后执行。

写触发器用的函数

首先要用PL/pgSQL写一个函数。这个函数会负责更新我们表里的last_modified字段。函数是触发器必须要有的,因为触发器只是告诉数据库“要干嘛”,具体怎么干都是函数来实现的。

先来建个表:

-- 创建表 students
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    age INT NOT NULL,
    last_modified TIMESTAMP
);

现在写个函数来更新last_modified字段:

-- 更新last_modified的函数
CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
    -- 把当前时间写进last_modified字段
    NEW.last_modified := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

来解释一下这个函数到底干了啥:

  • CREATE OR REPLACE FUNCTION update_last_modified() — 创建一个叫update_last_modified的函数。如果已经有同名的,会替换掉。
  • RETURNS TRIGGER — 说明这个函数是给触发器用的。
  • NEW.last_modified := NOW(); — 用NOW()函数把当前时间写进last_modified字段。
  • RETURN NEW; — 返回更新后的记录。AFTER类触发器必须要有这一步。

创建触发器

函数写好后,我们就能建触发器,把它绑到students表上。方法如下:

-- 插入后触发的触发器
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();

这里做了这些事:

  • CREATE TRIGGER set_last_modified — 创建一个叫set_last_modified的触发器。
  • AFTER INSERT — 这个触发器会在插入新行后执行。
  • ON students — 触发器绑在students表上。
  • FOR EACH ROW — 每插入一行都会执行一次。
  • EXECUTE FUNCTION update_last_modified(); — 调用我们刚写的函数。

注意:触发器名(set_last_modified)和函数名(update_last_modified)你可以随便起,不过最好按规范来,这样代码更容易懂。

测试触发器

来看看触发器到底好不好使。先往students表里插几条数据:

-- 往表里插数据
INSERT INTO students (name, age) VALUES ('伊万 伊万诺夫', 20);
INSERT INTO students (name, age) VALUES ('安娜 彼得罗娃', 22);

现在查查表里都有什么:

-- 查看表里的数据
SELECT * FROM students;

预期结果大概是这样:

id name age last_modified
1 奥托 明 20 2023-10-10 14:30:45
2 安娜 宋 22 2023-10-10 14:31:12

你会发现,last_modified字段已经自动填上了每条记录插入时的时间。

可能遇到的错误

  1. 错误:"relation does not exist" 创建触发器时报错。这个错一般是因为students表还没建好。先建表再建触发器。
  2. 权限错误。如果数据库用户没权限建函数或触发器,触发器就建不起来。检查一下用户权限。
  3. 触发器里没写函数调用。如果你忘了写EXECUTE FUNCTION update_last_modified(),触发器啥也不会干。

触发器进阶:加条件

实际开发中,有时候我们只想在满足某些条件时才让触发器执行。比如说,如果age字段小于18,我们就不想更新last_modified。可以用WHEN条件来搞定:

-- 带条件的触发器
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
WHEN (NEW.age >= 18)
EXECUTE FUNCTION update_last_modified();

这样只有年龄大于等于18的学生,last_modified才会被更新。

实际应用

像这种触发器,在实际项目里用得挺多。举几个例子:

  • 自动更新记录最后修改时间(就像我们现在做的)。
  • 监控数据库变化,把这些变化写进日志表。
  • 保证数据一致性,比如操作前检查相关表的数据。
  • 做数据审计,满足法律或公司要求。

这些技能特别有用,尤其是你要做那种对数据准确性和可靠性要求很高的系统,比如银行系统、库存管理系统或者CRM。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION