如何在触发器中获取更新前后的值_NEW与OLD伪记录的访问机制

张开发
2026/4/20 0:16:20 15 分钟阅读

分享文章

如何在触发器中获取更新前后的值_NEW与OLD伪记录的访问机制
MySQL和PostgreSQL中OLD/NEW字段需按触发时机BEFORE/AFTER、INSERT/UPDATE/DELETE正确访问区分大小写且不可跨数据库直接移植误用会导致报错或性能问题。触发器里怎么拿到 OLD 和 NEW 的字段值mysql 和 postgresql 都支持在行级触发器中用 old 和 new 引用修改前后的整行数据但访问方式不同不能直接当普通变量用。常见错误是写成 OLD.username 却忘了当前数据库不支持点号语法比如 PostgreSQL 在函数体里得用 OLD.username但 MySQL 里必须用 OLD.username——等等其实都支持问题出在别处更常踩的坑是在 BEFORE DELETE 触发器里还去读 NEW结果报错 NEW is not available in DELETE triggers。MySQL 中OLD 和 NEW 是只读伪记录字段名区分大小写且必须和表定义完全一致比如表字段是 user_name就不能写 OLD.usernamePostgreSQL 中OLD/NEW 是 RECORD 类型在 PL/pgSQL 函数里可直接用点号访问如 OLD.id但若触发器函数声明为 RETURNS trigger就必须返回 NEWINSERT/UPDATE或 OLDDELETE否则会中断操作SQLite 不支持 OLD/NEW 伪记录只能靠 UPDATE ... SET col old_col WHERE rowid ? 这类手动模拟本质没真触发器上下文BEFORE 和 AFTER 触发器对 OLD/NEW 的可用性差异不是所有时机都能同时访问两个伪记录。核心规则就一条哪个数据还存在才能读哪个。BEFORE INSERT只有 NEW 可用还没插入自然没有旧值BEFORE UPDATEOLD 和 NEW 都可用且 NEW 可被修改比如自动更新 updated_at 字段BEFORE DELETE只有 OLD 可用要删的是它没新行AFTER 类触发器中OLD/NEW 仍可读但不能再改 NEWMySQL 报错 Cant update table in stored function/triggerPostgreSQL 要求函数返回值匹配典型误用在 AFTER UPDATE 里试图给 NEW.status processed —— 这不会生效语句已执行完改了也白改。跨数据库移植时 OLD/NEW 的兼容性陷阱看着名字一样实际行为差很远。最痛的点是字段类型隐式转换和 NULL 处理。 知元AI AI智能语音聊天 对讲问答 AI绘画 AI写作 AI创作助手工具

更多文章