查清存储过程数量和调用关系是迁移前提:先用SELECT COUNT(*) FROM mysql.proc统计数量,再排查应用代码、其他过程、定时事件及ORM隐式调用;语法兼容需分层验证DECLARE、循环、函数、异常处理;依赖对象须全部就位;最小数据集验证逻辑与执行计划,避免隐式转换导致性能劣化。

查清存储过程数量和调用关系
不先盘点,就谈成本是拍脑袋。直接连上 MySQL 执行:SELECT COUNT(*) FROM mysql.proc WHERE db = 'your_db_name';,快速知道有多少个。但更关键的是谁在调用它们——应用代码里硬编码的调用、其他存储过程里的 CALL、定时事件(information_schema.EVENTS)、甚至 ORM 框架生成的 SQL 里可能隐式触发。漏掉一个跨过程调用,上线后就可能报 PROCEDURE not found。
逐条识别语法与函数兼容性缺口
达梦、金仓、PostgreSQL 等目标库对 MySQL 存储过程的支持不是“全有或全无”,而是分层断裂。重点扫这些:
-
DECLARE变量声明:MySQL 允许DECLARE v INT DEFAULT 0;,达梦要求显式INT := 0,金仓则接受但需确认是否启用 MySQL 兼容模式 -
WHILE/REPEAT块:达梦用LOOP...EXIT WHEN,金仓可保留但内部解析器可能对嵌套深度敏感 - 内置函数:如
DATE_ADD(NOW(), INTERVAL 1 DAY)在达梦中得改ADD_DAYS(SYSDATE, 1);GROUP_CONCAT在多数国产库中要换成LISTAGG+OVER() - 异常处理:
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION这类结构在达梦中必须重写为EXCEPTION WHEN OTHERS THEN,且错误码映射不一致
验证依赖对象是否已就位
一个存储过程哪怕语法全通,只要它查了还没迁的视图、用了未创建的自定义函数、或依赖某个 MySQL 特有分区策略(如 KEY 分区),就会在 CREATE OR REPLACE PROCEDURE 阶段直接失败。迁移前必须确认:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 所有被
SELECT/INSERT INTO引用的表、视图已在目标库存在,且字段名/类型一致(注意TINYINT(1)在达梦里默认转成NUMBER(1),但逻辑含义可能是布尔) - 过程内调用的其他存储过程或函数,已按相同规则完成评估和改造,不能只迁 A 而不迁它依赖的 B
- 涉及权限的操作(如
SELECT ... INTO OUTFILE)在目标库是否被禁用,是否需改用临时表或应用层拼接
跑通最小数据集+监控执行计划变化
语法能编译通过 ≠ 逻辑正确 ≠ 性能可接受。拿一个典型过程,用 10–20 行代表性数据在两边分别执行:
- 比对输出结果:空值处理(MySQL 的
NULL与达梦的NULL行为一致,但字符串拼接时CONCAT('a', NULL)在 MySQL 返回NULL,达梦默认返回'a',需加SET NULLS ON) - 看执行计划:
EXPLAIN FORMAT=TREE(MySQL) vsEXPLAIN PLAN FOR(达梦),关注是否出现全表扫描替代了原索引扫描——常见于隐式类型转换,比如过程参数是VARCHAR,但传入数字导致字段索引失效 - 测事务边界:MySQL 中
START TRANSACTION内的CALL是否在目标库仍保持原子性,尤其涉及游标和临时表时
真正卡住进度的,往往不是语法转换本身,而是某条 UPDATE 语句在目标库因统计信息不准导致执行时间从 0.2 秒涨到 12 秒,而这个现象只在真实数据分布下暴露。别跳过这步压测。










