在数据库迁移的实际场景中,Oracle和MySQL的语法差异会导致原有Oracle语句无法直接在新库中运行,需要针对性调整语句结构、替换适配函数。下面梳理常见的转换场景和具体实现方法。

常见数据类型转换
Oracle和MySQL的基础数据类型定义存在差异,迁移时需要对应调整字段类型,避免数据存储异常。常见类型对应关系如下:
| Oracle数据类型 | MySQL对应数据类型 | 说明 |
|---|---|---|
| VARCHAR2(n) | VARCHAR(n) | 长度定义规则一致,注意MySQL的VARCHAR最大长度受字符集影响 |
| NUMBER(p,s) | DECIMAL(p,s) | 数值精度定义规则兼容,可直接替换 |
| DATE | DATETIME | Oracle的DATE包含日期和时间,MySQL的DATE仅含日期,需替换为DATETIME保留时间信息 |
| CLOB | TEXT | 大文本类型适配,注意MySQL的TEXT有长度限制,超长内容可使用LONGTEXT |
常用函数转换
日期函数转换
Oracle的日期处理函数和MySQL差异较大,最常用的是获取当前时间和日期格式化场景。
Oracle中获取当前时间使用SYSDATE,MySQL中对应使用NOW()或者CURRENT_TIMESTAMP:
-- Oracle原语句 SELECT SYSDATE FROM DUAL; -- MySQL转换后语句 SELECT NOW();
Oracle的日期格式化函数TO_CHAR(date, format),在MySQL中需要替换为DATE_FORMAT(date, format),格式符也需要对应调整:
-- Oracle原语句,格式化日期为年-月-日 时:分:秒 SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL; -- MySQL转换后语句,格式符%Y对应四位年,%m对应月,%d对应日,%H对应24小时制小时 SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
空值判断函数转换
Oracle的NVL(expr1, expr2)函数用于判断expr1是否为空,为空则返回expr2,MySQL中对应使用IFNULL(expr1, expr2):
-- Oracle原语句,若name为空则返回未知 SELECT NVL(name, '未知') FROM user_table; -- MySQL转换后语句 SELECT IFNULL(name, '未知') FROM user_table;
如果是多条件空值判断,Oracle的NVL2(expr1, expr2, expr3)(expr1不为空返回expr2,为空返回expr3),MySQL中可以用IF(expr1 IS NOT NULL, expr2, expr3)实现:
-- Oracle原语句 SELECT NVL2(age, '成年', '未成年') FROM user_table; -- MySQL转换后语句 SELECT IF(age IS NOT NULL, '成年', '未成年') FROM user_table;
分页语法转换
Oracle常用的分页方式是结合ROWNUM实现,MySQL的分页使用LIMIT关键字,语法结构差异较大。
Oracle分页示例,查询第11到20条数据:
-- Oracle原分页语句
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
SELECT * FROM user_table ORDER BY id
) t WHERE ROWNUM <= 20
) WHERE rn >= 11;MySQL转换后分页语句,LIMIT第一个参数是偏移量(从0开始),第二个参数是查询条数:
-- MySQL转换后分页语句,偏移量10对应第11条,查询10条对应到20条 SELECT * FROM user_table ORDER BY id LIMIT 10, 10;
字符串连接转换
Oracle中字符串连接可以使用||运算符或者CONCAT函数,MySQL中||默认是逻辑或运算符,字符串连接需要使用CONCAT函数,且CONCAT只支持两个参数,多字符串连接需要嵌套使用:
-- Oracle原语句,连接姓名和年龄
SELECT name || '的年龄是' || age FROM user_table;
-- MySQL转换后语句,嵌套CONCAT实现多字符串连接
SELECT CONCAT(CONCAT(name, '的年龄是'), age) FROM user_table;
-- 也可以使用CONCAT_WS函数,第一个参数是分隔符,后续参数直接拼接
SELECT CONCAT_WS('', name, '的年龄是', age) FROM user_table;其他注意事项
- Oracle的
DUAL伪表在MySQL中不需要使用,直接执行函数或者表达式即可,比如SELECT 1+1在MySQL中可以直接运行,不需要加FROM DUAL。 - Oracle的
DECODE函数(条件判断返回对应值),MySQL中可以用CASE WHEN语句替换,例如DECODE(status, 1, '启用', 0, '禁用', '未知')转换为CASE WHEN status=1 THEN '启用' WHEN status=0 THEN '禁用' ELSE '未知' END。 - MySQL对关键字的大小写不敏感,但建议统一语句风格,避免和保留关键字冲突,如果有字段名和保留关键字重复,需要用反引号包裹字段名。
Oracle迁移MySQLSQL语句转换数据库迁移语法差异修改时间:2026-06-06 23:26:48