SQL触发器实现自动生成流水号_配合序列对象实现递增逻辑
触发器中调用NEXTVAL报错主因是语法误用Oracle应使用赋值语句:NEW.id : seq_name.NEXTVAL而非SELECT INTOPostgreSQL须用nextval(seq_name)MySQL无原生序列需借AUTO_INCREMENT与LAST_INSERT_ID()模拟。触发器里调用 NEXTVAL 为什么总报错常见错误是直接在 BEFORE INSERT 触发器里写 SELECT seq_name.NEXTVAL INTO :NEW.id FROM DUAL但 Oracle 要求这种查询必须是「确定性」的——而触发器里隐式执行的 SELECT ... FROM DUAL 在某些版本尤其是 12c 多租户环境会因上下文缺失报 ORA-04091: table is mutating 或 ORA-00904: invalid identifier。正确做法是用 :NEW.id : seq_name.NEXTVALPL/SQL 赋值语法不走 SELECT INTOPostgreSQL 则必须用 NEXTVAL(seq_name) 函数调用且只能在 BEFORE INSERT 的 EXECUTE FUNCTION 中安全使用MySQL 没原生序列得用 AUTO_INCREMENT LAST_INSERT_ID() 模拟不能在触发器里再查自己表BEFORE INSERT 还是 AFTER INSERT流水号必须在插入前生成并赋给主键字段否则主键冲突或空值报错。所以一律用 BEFORE INSERTAFTER INSERT 只能改非主键字段或者写日志没法补流水号。Oracle / PostgreSQL在 BEFORE INSERT FOR EACH ROW 中直接赋值 :NEW.no : seq_name.NEXTVAL如果业务要求「按日期分段编号」如 20240520-0001得在触发器里拼字符串但注意 TO_CHAR(SYSDATE, YYYYMMDD) 要加 NLS_DATE_FORMAT 防环境差异别在 AFTER 触发器里尝试 UPDATE 同一张表——必然触发 mutating table 错误并发场景下 NEXTVAL 会跳号吗会而且这是正常行为不是 bug。序列对象本质是缓存 原子递增只要调用了 NEXTVAL 就占一个号哪怕事务回滚、触发器异常退出、甚至连接中断。 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手依托大模型帮助用户记录、整理和分析音视频内容体验用大模型做音视频笔记、整理会议记录。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2538032.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!