navicat不支持触发器迁移是设计缺陷,因其完全忽略information_schema.triggers表,不解析定义、不处理definer依赖、不保障执行顺序,跨库迁移时触发器必然丢失,需人工导出、改写、重建。

Navicat 本身不把触发器当「可迁移对象」处理,跨系统迁移时丢触发器不是偶然失误,而是设计如此——它压根不读 information_schema.TRIGGERS 表,也不解析触发器定义。
Navicat 数据传输根本不会拉取触发器元数据
你看到的「表结构 + 数据」迁移结果里没有触发器,是因为 Navicat 的数据传输逻辑只查 information_schema.TABLES、information_schema.COLUMNS、information_schema.KEY_COLUMN_USAGE 这几张表。哪怕源库有 200 个 BEFORE INSERT 触发器,只要没显式导出或重建,目标库就一定为空。
- 跨 MySQL→MySQL 迁移:触发器仍丢失(不是 bug,是功能缺失)
- 跨 Oracle→MySQL 或 SQL Server→PostgreSQL:Navicat 自动类型转换完全忽略源端触发器逻辑,比如 Oracle 的
BEFORE INSERT FOR EACH ROW BEGIN ... :new.id := seq.nextval; END;不会生成任何对应 MySQL 触发器 - 即使勾选了「Stored Procedures and Functions」,也不会连带导出触发器——那是两个独立复选框,且「Triggers」默认不勾选
备份界面勾选「Triggers」也未必能保全
右键数据库 → Backup Database → 勾选 Triggers,确实能导出 CREATE TRIGGER 语句,但存在三个硬伤:
- 导出的语句含原始
DEFINER='admin'@'localhost',若目标库无该用户,执行直接报错ERROR 1449 (HY000): The user specified as a definer ('admin'@'localhost') does not exist - Navicat 不自动替换
SQL SECURITY DEFINER为INVOKER,权限校验失败时静默跳过或中断 - 导出文件里触发器顺序不保证依赖关系,比如函数先于触发器创建,但还原脚本可能反着执行,导致
FUNCTION does not exist
跨异构库时触发器逻辑必须人工重写
Oracle 的 SEQUENCE + TRIGGER 主键生成、PostgreSQL 的 GENERATED ALWAYS AS IDENTITY、SQL Server 的 INSTEAD OF 视图触发器,在 Navicat 迁移中全部被降级为字段默认值或 AUTO_INCREMENT,而真正控制行为的触发器体被丢弃。
- 检查源库是否真有触发器驱动逻辑:
SELECT trigger_name FROM user_triggers WHERE table_name = 'YOUR_TABLE';(Oracle)或SELECT tgname FROM pg_trigger JOIN pg_class ON tgrelid = relid WHERE relname = 'your_table';(PostgreSQL) - MySQL 5.7+ 才支持
BEFORE INSERT触发器修改NEW.id;低于此版本只能靠应用层或存储过程补位 - 别依赖 Navicat「同步到模型」再「模型同步到数据库」来回倒腾——模型里触发器只是灰色文本块,不解析
OLD/NEW字段,也无法校验语法合法性
真正关键的点在于:触发器不是“附属结构”,而是业务逻辑的一部分。Navicat 把它当作装饰性元数据处理,但数据库执行时它会真实拦截、改写、拒绝每一条 DML。漏掉一个,轻则主键冲突,重则数据不一致,且问题往往延迟暴露。











