错误一:盲目相信语法兼容性报告
很多国产数据库宣称兼容Oracle语法,但实际只覆盖了常用SQL。真实案例:某系统用了Oracle的CONNECT BY层次查询,迁移后虽然能跑,但结果集排序与Oracle不一致,导致报表数据错位。对策:迁移前使用静态SQL扫描工具,找出所有非标准语法,并逐条在目标库上做结果比对,而不是只验证能否执行。
错误二:忽略数据类型精度差异
Oracle的NUMBER是变长精度,而国产库常用DECIMAL(38,10)固定精度。当业务字段定义为NUMBER且无精度限制时,迁移工具默认映射为DECIMAL(38,0),小数位被截断,金额计算直接出错。对策:迁移前导出所有表的DDL,人工审查每个NUMBER字段的实际使用精度,必要时在目标库中调整字段定义,并在迁移后做数据抽样比对。
错误三:隐式类型转换导致索引失效
Oracle中WHERE varchar_col = 123会隐式转换,但国产库可能将列转为数字,导致索引失效全表扫描。更隐蔽的是日期字符串格式差异,TO_DATE函数在不同库中的默认格式不同。对策:在应用层强制类型转换,修改SQL为WHERE varchar_col = '123',同时启用目标库的慢查询日志,迁移后监控一周,找出所有全表扫描的高频SQL。
错误四:序列与自增主键的语义差异
Oracle的SEQUENCE不保证连续性,但国产库的AUTO_INCREMENT在回滚时会回收ID,导致主键冲突。某电商订单表迁移后,并发插入时频繁报唯一键冲突。对策:迁移后统一改用目标库的序列对象,并设置合理的缓存大小,避免每次插入都访问序列造成性能瓶颈。
错误五:分区表语法不兼容
Oracle的RANGE分区支持MAXVALUE,而部分国产库不支持,导致迁移脚本报错。另外,分区裁剪优化器的能力差异,可能让原本走分区裁剪的查询变成全分区扫描。对策:提前用目标库的分区语法重写建表语句,并用真实查询计划对比分区裁剪是否生效。
错误六:存储过程与包体的边界行为
Oracle的PL/SQL支持包(Package)和自治事务,国产库往往只支持基础存储过程,且异常处理行为不同。例如NO_DATA_FOUND异常在Oracle中只触发一次,但在某些国产库中会持续传播导致事务回滚。对策:迁移前梳理所有存储过程,优先重写复杂的包体为普通函数,并在测试环境模拟异常路径,验证事务提交与回滚行为。
最终建议:迁移不是一次性任务,建议采用双写双读的灰度方案,先并行运行3个月,对比数据一致性和性能差异,再切换流量。同时保留回滚脚本,确保任何时刻都能快速切回Oracle。