讲师中心 微信公众号
AI工具推荐 视频效率加速

怎样在SQL触发器中获取更新前后的字段值

冬婷小哥_2485

冬婷小哥_2485

发布时间:2026-07-30 16:08:24

|

455人浏览过

|

来源于php中文网

原创

UPDATE触发器中OLD代表更新前行、NEW代表更新后行,二者为只读伪记录,须用OLD.col、NEW.col访问字段;BEFORE中可修改NEW字段,AFTER中仅可读;判断变更需空安全比较,如NOT (OLD.col <=> NEW.col)。

怎样在sql触发器中获取更新前后的字段值

MySQL触发器里用 OLD 和 NEW 拿字段值

在 UPDATE 触发器中,OLD 代表更新前的行,NEW 代表更新后的行。它们不是变量,而是伪记录(pseudo-record),只能在触发器体中直接点字段访问,比如 OLD.name、NEW.email。

常见错误是试图把 OLD 或 NEW 当成普通变量赋值或判空——它们不能被赋值,也不能直接 IS NULL 判断整行;必须对具体字段操作。

  • BEFORE UPDATE 中可读可写 NEW 字段(改了会影响实际更新结果),但 OLD 只读
  • AFTER UPDATE 中 OLD 和 NEW 都只读,适合审计日志
  • 对未修改的字段,OLD.col = NEW.col 成立;想判断某字段是否真被改过,得显式比较:IF OLD.status != NEW.status THEN ...

PostgreSQL触发器要靠 OLD / NEW + ROW 类型变量

PG 的触发器函数是独立的 PL/pgSQL 函数,没有隐式 OLD/NEW。你得在函数定义时声明参数接收它们:

CREATE OR REPLACE FUNCTION log_user_change()
RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'UPDATE' THEN
    INSERT INTO user_audit (user_id, old_email, new_email, changed_at)
    VALUES (OLD.id, OLD.email, NEW.email, NOW());
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

注意三点:

  • 函数必须返回 NEW(INSERT/UPDATE)或 OLD(DELETE),否则触发器会中断操作
  • TG_OP 是内置变量,值为 'INSERT'、'UPDATE' 或 'DELETE',别硬写字符串比较
  • 如果表有 JSONB 或大字段,直接存 OLD/NEW 整行可能触发 TOAST 开销;建议只取必要字段

SQL Server触发器依赖 inserted 和 deleted 临时表

SQL Server 不提供行级伪记录,而是用两个内存临时表:inserted(含新值)和 deleted(含旧值)。UPDATE 操作会同时填充两张表,INSERT 只填 inserted,DELETE 只填 deleted。

典型误用是假设 inserted 和 deleted 总是一一对应——其实它们是表,可能多行,必须用 JOIN 关联主键才能匹配前后值:

SELECT d.id, d.name AS old_name, i.name AS new_name
FROM deleted d
INNER JOIN inserted i ON d.id = i.id
WHERE d.name != i.name;
  • 不能在触发器里对原表做 SELECT * FROM 表名,可能引发递归或死锁
  • 如果业务逻辑需要查其他表,优先用 EXISTS 而非 IN,避免 NULL 导致意外跳过
  • 触发器执行期间,inserted/deleted 表不可被其他会话访问,也不支持索引——大数据量更新时性能容易掉

跨数据库通用坑:NULL 值比较和字符集隐式转换

所有数据库都默认用三值逻辑处理 NULL:直接写 OLD.col != NEW.col 在任一字段为 NULL 时结果是 UNKNOWN,条件不成立。必须显式处理:

  • MySQL/PG:用 IS DISTINCT FROM(PG 原生支持,MySQL 8.0.22+ 支持)或手写 (OLD.col != NEW.col) OR (OLD.col IS NULL) != (NEW.col IS NULL)
  • SQL Server:用 ISNULL(OLD.col, '') != ISNULL(NEW.col, ''),但要注意类型一致(比如 INT 不能直接和空字符串比)
  • 如果字段是 VARCHAR 且库/表字符集不同(如 utf8mb4 vs latin1),OLD.col = NEW.col 可能因隐式转换失败报错,建议统一字符集或显式 CONVERT

触发器里最隐蔽的问题往往不在逻辑,而在这些边界值和类型细节上——一次 NULL 比较漏判,就可能让关键审计字段永远不入库。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4323

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

911

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1129

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6241

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3083

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6220

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

8441

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1150

2024.04.29

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

20

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
布尔教育燕十八mysql高级视频教程
布尔教育燕十八mysql高级视频教程

共24课时 | 8.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn