aws sct 能自动转换 oracle 模式到 mysql 8.0,但必须手动处理 sequence、synonym、dblink、with 递归查询、rownum 分页及全部 pl/sql 逻辑;否则表可建出,业务一跑即报错。

直接说结论:AWS SCT 能自动转换 Oracle 模式到 MySQL 8.0,但“平滑”不等于“全自动”——必须手动处理 SEQUENCE、SYNONYM、DBLINK、WITH 递归查询、ROWNUM 分页,以及所有 PL/SQL 逻辑。否则迁移后表能建出来,业务一跑就报错。
为什么 AWS SCT 生成的 MySQL DDL 会缺主键或乱用 TEXT?
AWS SCT 默认按 Oracle 的语义做保守映射,比如:NUMBER(10) 映射成 DECIMAL(10,0) 而非 BIGINT;VARCHAR2(4000) 映射成 TEXT(而非 VARCHAR(4000)),因为 MySQL 5.7+ 的 VARCHAR 最大长度受行大小限制;DATE 类型会丢掉时区信息,变成无时区的 DATETIME。
常见后果:
- MySQL 表没有主键(Oracle 原表用的是
ROWID或未显式定义 PK,SCT 不会自动补) -
TEXT字段无法建索引,导致 WHERE 查询全表扫描 -
NOT NULL约束丢失(Oracle 的NOT NULL在某些视图或物化视图场景下不被 SCT 识别)
实操建议:
- 迁移前在 Oracle 中执行
SELECT table_name, column_name FROM all_tab_columns WHERE nullable = 'N' AND data_type IN ('VARCHAR2','CHAR','NUMBER'),导出非空字段清单,人工核对 SCT 生成的 DDL - 把 SCT 输出的
TEXT改成VARCHAR(16383)(MySQL 8.0.30+ 支持最大 16383 字符的VARCHAR),并加NOT NULL DEFAULT ''避免 NULL 冲突 - 用
mysqlsh --sql -e "ALTER TABLE ... ADD PRIMARY KEY (...)"批量补主键
PL/SQL 存储过程和函数怎么转成 MySQL 8.0 兼容版本?
AWS SCT 自带 oracle_to_mysql 扩展包,但它只覆盖基础函数(如 TO_CHAR → DATE_FORMAT、NVL → IFNULL),不处理流程控制、游标、异常块、自治事务等。
典型翻车点:
-
FOR rec IN (SELECT ...) LOOP ... END LOOP;→ MySQL 不支持隐式游标,必须改写为DECLARE cur CURSOR FOR ...; OPEN cur; FETCH cur INTO ...; -
EXCEPTION WHEN NO_DATA_FOUND THEN ...→ MySQL 只有DECLARE ... HANDLER FOR NOT FOUND,且 handler 作用域仅限当前 BEGIN...END 块 -
PRAGMA AUTONOMOUS_TRANSACTION→ MySQL 完全不支持,必须拆成应用层两阶段提交
实操建议:
- 不要依赖 SCT 自动生成的存储过程,把它当伪代码看——只抄结构,逻辑重写
- 把 Oracle 的
SEQUENCE.NEXTVAL全部替换成AUTO_INCREMENT+LAST_INSERT_ID(),并在 INSERT 后立刻读取 - 用
mysqlsh --util checkForProblems --target mysql://user@host:3306/db扫描语法兼容性问题
离线模式下如何验证转换后的 SQL 能真正执行?
SCT 离线模式能编辑、保存、导出转换结果,但不会连接目标库校验语法或权限。你导出的 .sql 文件可能含 MySQL 8.0 不支持的语法(如 CREATE OR REPLACE VIEW 在 MySQL 8.0.19 才支持)。
容易被忽略的坑:
- Oracle 的
WITH递归查询(START WITH ... CONNECT BY)被 SCT 转成 MySQL 8.0 的 CTE,但若嵌套过深或引用自身别名错误,会报ERROR 3636 (HY000): Recursive query aborted after 1001 iterations - SCT 生成的
CREATE FUNCTION默认带DETERMINISTIC,但若函数里查了表,MySQL 会拒绝创建(必须改成READS SQL DATA) - 目标 MySQL 用户没被授予
CREATE ROUTINE和ALTER ROUTINE权限,CREATE PROCEDURE直接失败
实操建议:
- 先用
mysql --no-defaults -u user -p -e "source converted_schema.sql" mysql测试 DDL 是否能过(注意加--no-defaults避免客户端配置干扰) - 对每个生成的函数/存储过程,单独执行
SHOW CREATE FUNCTION func_name,检查SQL SECURITY和DETERMINISTIC标记是否合理 - 在 MySQL 8.0 上运行
SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'your_db',确认所有 routine 状态是VALID
最常被跳过的一步:SCT 不处理数据一致性校验。它只管结构和代码转换,不保证 Oracle 里的 TO_DATE('2025-01-01','YYYY-MM-DD') 在 MySQL 里解析成相同时间戳——尤其当 NLS_DATE_FORMAT 不一致时。上线前务必用抽样比对工具(如 pt-table-checksum 或自写脚本)核对关键表的 CRC32 值。











