目录


版本兼容性说明

  • Oracle 11g+ 支持大部分窗口函数,12c+支持FETCH分页、IDENTITY自增等。
  • SQL Server 2012+ 支持窗口函数、OFFSET分页、TRY_CAST等。
  • MySQL 8.0+ 支持窗口函数、正则、JSON_TABLE等,5.7+支持部分JSON函数。
  • 如无特殊说明,示例均以主流新版本为准。

一、字符串函数

函数功能OracleSQL ServerMySQL参数说明版本要求
字符串连接CONCAT(str1, str2)CONCAT(str1, str2)CONCAT(str1, str2, ...)Oracle最多2个参数,SQL Server/MySQL支持多个参数拼接11g+
子串截取SUBSTR(str,start,len)SUBSTRING(str,start,len)SUBSTRING(str, start, len)起始位置从1开始,len为截取长度11g+
字符串长度LENGTH(str)LEN(str)LENGTH(str)返回字符数(中文按1计算)11g+
去除首尾空格TRIM(str)LTRIM(RTRIM(str))TRIM(str)Oracle支持单边TRIM(LEADING/TRAILING),MySQL同理11g+
大小写转换LOWER(str) / UPPER(str)同左同左全数据库通用11g+

SQL示例对照

1. 字符串函数

  • Oracle

    1
    
    SELECT CONCAT('A', 'B'), SUBSTR('Hello', 2, 3), LENGTH('中国'), TRIM('  abc  '), LOWER('ABC') FROM dual;
    
  • SQL Server

    1
    
    SELECT CONCAT('A', 'B'), SUBSTRING('Hello', 2, 3), LEN('中国'), LTRIM(RTRIM('  abc  ')), LOWER('ABC');
    
  • MySQL

    1
    
    SELECT CONCAT('A', 'B'), SUBSTRING('Hello', 2, 3), LENGTH('中国'), TRIM('  abc  '), LOWER('ABC');
    

二、日期函数

函数功能OracleSQL ServerMySQL参数说明版本要求
当前日期时间SYSDATEGETDATE()NOW()无参数,返回服务器当前时间11g+
日期格式化TO_CHAR(date,'YYYY-MM-DD')CONVERT(VARCHAR, date, 120)DATE_FORMAT(date, '%Y-%m-%d')Oracle格式代码自由,SQL Server用风格代码,MySQL用格式字符串11g+
日期加减date + NDATEADD(unit, N, date)DATE_ADD(date, INTERVAL N unit)Oracle直接加减天数,SQL Server/MySQL需指定单位11g+
提取日期部分EXTRACT(YEAR FROM date)DATEPART(YEAR, date)YEAR(date)支持year/month/day/hour等时间单位11g+

SQL示例对照

2. 日期函数

  • Oracle

    1
    
    SELECT SYSDATE, TO_CHAR(SYSDATE, 'YYYY-MM-DD'), SYSDATE + 1, EXTRACT(YEAR FROM SYSDATE) FROM dual;
    
  • SQL Server

    1
    
    SELECT GETDATE(), CONVERT(VARCHAR, GETDATE(), 120), DATEADD(day, 1, GETDATE()), DATEPART(YEAR, GETDATE());
    
  • MySQL

    1
    
    SELECT NOW(), DATE_FORMAT(NOW(), '%Y-%m-%d'), DATE_ADD(NOW(), INTERVAL 1 DAY), YEAR(NOW());
    

三、数学函数

函数功能OracleSQL ServerMySQL参数说明版本要求
绝对值ABS(num)同左同左全数据库通用11g+
向上取整CEIL(num)CEILING(num)CEIL(num)返回大于等于参数的最小整数11g+
向下取整FLOOR(num)同左同左返回小于等于参数的最大整数11g+
四舍五入ROUND(num,精度)同左同左参数1为数值,参数2为保留小数位数11g+

SQL示例对照

3. 数学函数

  • Oracle

    1
    
    SELECT ABS(-5), CEIL(2.3), FLOOR(2.7), ROUND(3.1415, 2) FROM dual;
    
  • SQL Server

    1
    
    SELECT ABS(-5), CEILING(2.3), FLOOR(2.7), ROUND(3.1415, 2);
    
  • MySQL

    1
    
    SELECT ABS(-5), CEIL(2.3), FLOOR(2.7), ROUND(3.1415, 2);
    

四、聚合函数

函数功能OracleSQL Server参数说明版本要求
字符串聚合LISTAGG(str,分隔符) WITHIN GROUP(...)STRING_AGG(str,分隔符) WITHIN GROUP(...)Oracle支持ON OVERFLOW TRUNCATE截断,SQL Server需手动处理超长‌1311g+
空值替换NVL(expr1, expr2)ISNULL(expr1, expr2)expr1为NULL时返回expr2‌2411g+

SQL示例对照

4. 聚合函数

  • Oracle

    1
    2
    
    SELECT LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS names FROM emp;
    SELECT NVL(comm, 0) FROM emp;
    
  • SQL Server

    1
    2
    
    SELECT STRING_AGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS names FROM emp;
    SELECT ISNULL(comm, 0) FROM emp;
    
  • MySQL

    1
    2
    
    SELECT GROUP_CONCAT(ename ORDER BY ename SEPARATOR ',') AS names FROM emp;
    SELECT IFNULL(comm, 0) FROM emp;
    

五、类型转换函数

函数功能OracleSQL Server参数说明版本要求
类型转换TO_NUMBER(str)CAST(str AS NUMERIC) / CONVERT(NUMERIC, str)SQL Server推荐使用TRY_CAST避免转换失败‌4511g+
日期转字符串TO_CHAR(date,格式)CONVERT(VARCHAR, date, 格式代码)Oracle格式如'YYYY-MM-DD',SQL Server用数字代码如112‌2511g+

SQL示例对照

5. 类型转换函数

  • Oracle

    1
    
    SELECT TO_NUMBER('123'), TO_CHAR(SYSDATE, 'YYYY-MM-DD') FROM dual;
    
  • SQL Server

    1
    
    SELECT CAST('123' AS NUMERIC), CONVERT(VARCHAR, GETDATE(), 112);
    
  • MySQL

    1
    
    SELECT CAST('123' AS DECIMAL), DATE_FORMAT(NOW(), '%Y-%m-%d');
    

六、条件函数

函数功能OracleSQL Server参数说明版本要求
条件判断DECODE(expr, val1, res1, default)CASE WHEN expr = val1 THEN res1 ELSE default ENDOracle特有DECODE,SQL Server用标准CASE‌2411g+
空值处理NVL2(expr, res1, res2)COALESCE(expr, res1, res2)Oracle根据expr是否为NULL返回不同结果,SQL Server用多参数合并‌4611g+

SQL示例对照

6. 条件函数

  • Oracle

    1
    2
    
    SELECT DECODE(sex, 'M', '男', 'F', '女', '未知') FROM person;
    SELECT NVL2(comm, '有提成', '无提成') FROM emp;
    
  • SQL Server

    1
    2
    
    SELECT CASE WHEN sex = 'M' THEN '男' WHEN sex = 'F' THEN '女' ELSE '未知' END FROM person;
    SELECT COALESCE(comm, '无提成') FROM emp;
    
  • MySQL

    1
    2
    
    SELECT IF(sex = 'M', '男', IF(sex = 'F', '女', '未知')) FROM person;
    SELECT IFNULL(comm, '无提成') FROM emp;
    

七、NULL相关函数

函数功能OracleSQL Server参数说明版本要求
条件判断NVL(expr1, expr2)ISNULL(expr1, expr2)expr1为NULL时返回expr2‌2411g+
空值处理COALESCE(expr, res1, res2)COALESCE(expr, res1, res2)合并多个参数,返回第一个非NULL值‌4611g+

SQL示例对照

7. NULL相关函数

  • Oracle

    1
    
    SELECT NVL(comm, 0), COALESCE(comm, bonus, 0), CASE WHEN comm IS NULL THEN 1 ELSE 0 END FROM emp;
    
  • SQL Server

    1
    
    SELECT ISNULL(comm, 0), COALESCE(comm, bonus, 0), CASE WHEN comm IS NULL THEN 1 ELSE 0 END FROM emp;
    
  • MySQL

    1
    
    SELECT IFNULL(comm, 0), IFNULL(bonus, 0), IF(comm IS NULL, 1, 0) FROM emp;
    

八、分组与窗口函数

函数功能OracleSQL ServerMySQL参数说明版本要求
行号ROWNUM / ROW_NUMBER() OVER(...)ROW_NUMBER() OVER(...)ROW_NUMBER() OVER(...)返回分组内行号11g+
累计/排名RANK() OVER(...) / DENSE_RANK() OVER(...)同左同左分组排名11g+
分组求和SUM(col) OVER(PARTITION BY ...)同左同左分组累计11g+
移动平均AVG(col) OVER(ORDER BY ... ROWS BETWEEN N PRECEDING AND CURRENT ROW)同左同左计算滑动窗口平均值11g+
首/末值FIRST_VALUE(col) OVER(...) / LAST_VALUE(col) OVER(...)同左同左获取分组内首/末值11g+
行间差值LAG(col, N, default) OVER(...) / LEAD(col, N, default) OVER(...)同左同左获取前/后N行的值11g+

SQL示例对照

8. 分组与窗口函数

  • Oracle

    1
    2
    
    SELECT ename, ROW_NUMBER() OVER(ORDER BY sal DESC) AS rn FROM emp;
    SELECT deptno, SUM(sal) OVER(PARTITION BY deptno) AS total_sal FROM emp;
    
  • SQL Server

    1
    2
    
    SELECT ename, ROW_NUMBER() OVER(ORDER BY sal DESC) AS rn FROM emp;
    SELECT deptno, SUM(sal) OVER(PARTITION BY deptno) AS total_sal FROM emp;
    
  • MySQL

    1
    2
    
    SELECT ename, ROW_NUMBER() OVER(ORDER BY sal DESC) AS rn FROM emp;
    SELECT deptno, SUM(sal) OVER(PARTITION BY deptno) AS total_sal FROM emp;
    

九、JSON处理函数

函数功能OracleSQL ServerMySQL参数说明版本要求
解析JSONJSON_VALUE(json_col, '$.key')JSON_VALUE(json_col, '$.key')JSON_EXTRACT(json_col, '$.key')提取JSON字段值11g+
JSON对象转表JSON_TABLE(json_col, '$.items[*]' COLUMNS(...))OPENJSON(json_col)JSON_TABLE(json_col, '$')拆分JSON数组为多行11g+
判断JSON有效IS JSONISJSON(json_col)ISJSON(json_col)判断字符串是否为合法JSON11g+

SQL示例对照

9. JSON处理函数

  • Oracle

    1
    
    SELECT JSON_VALUE('{"a":1}', '$.a') FROM dual;
    
  • SQL Server

    1
    2
    
    SELECT JSON_VALUE('{"a":1}', '$.a');
    SELECT * FROM OPENJSON('[{"id":1},{"id":2}]');
    
  • MySQL

    1
    2
    
    SELECT JSON_EXTRACT('{"a":1}', '$.a');
    SELECT * FROM JSON_TABLE('[{"id":1},{"id":2}]', '$');
    

十、空间/地理函数

函数功能OracleSQL ServerMySQL参数说明版本要求
创建点SDO_GEOMETRY(...)geometry::STPointFromText(...)ST_GeomFromText(...)创建空间点对象11g+
距离计算SDO_GEOM.SDO_DISTANCE(...)geometry::STDistance(...)ST_Distance(...)计算空间距离11g+
空间相交SDO_RELATE(...)geometry::STIntersects(...)ST_Intersects(...)判断空间对象是否相交11g+

SQL示例对照

10. 空间/地理函数

  • Oracle

    1
    
    SELECT SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(116.4, 39.9, NULL), NULL, NULL) FROM dual;
    
  • SQL Server

    1
    
    SELECT geometry::STPointFromText('POINT(116.4 39.9)', 4326);
    
  • MySQL

    1
    
    SELECT ST_GeomFromText('POINT(116.4 39.9)');
    

十一、错误处理与异常

函数功能OracleSQL ServerMySQL参数说明版本要求
异常捕获BEGIN ... EXCEPTION WHEN ... THEN ... END;BEGIN TRY ... END TRY BEGIN CATCH ... END CATCHBEGIN ... END TRY BEGIN CATCH ... END CATCH均支持块级异常处理11g+
抛出异常RAISE_APPLICATION_ERROR(-20001, 'msg')THROW 50001, 'msg', 1THROW 50001, 'msg', 1自定义错误抛出11g+

SQL示例对照

11. 错误处理与异常

  • Oracle

    1
    2
    3
    4
    5
    6
    
    BEGIN
      -- 代码
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('出错');
    END;
    
  • SQL Server

    1
    2
    3
    4
    5
    6
    
    BEGIN TRY
      -- 代码
    END TRY
    BEGIN CATCH
      PRINT '出错';
    END CATCH;
    
  • MySQL

    1
    2
    3
    4
    5
    6
    
    BEGIN
      -- 代码
    END TRY
    BEGIN CATCH
      SELECT '出错';
    END CATCH;
    

十二、序列与自增

函数功能OracleSQL ServerMySQL参数说明版本要求
创建序列CREATE SEQUENCE seq_name ...CREATE SEQUENCE seq_name ...CREATE SEQUENCE seq_name ...语法类似,参数略有差异12c+
获取下值seq_name.NEXTVALNEXT VALUE FOR seq_nameLAST_INSERT_ID()获取序列下一个值12c+
自增主键GENERATED AS IDENTITY(12c+)/NUMBER GENERATED BY DEFAULTIDENTITY(1,1)AUTO_INCREMENT字段属性定义自增12c+

SQL示例对照

12. 序列与自增

  • Oracle

    1
    2
    3
    
    CREATE SEQUENCE seq_test;
    SELECT seq_test.NEXTVAL FROM dual;
    CREATE TABLE t1(id NUMBER GENERATED BY DEFAULT AS IDENTITY, name VARCHAR2(20));
    
  • SQL Server

    1
    2
    3
    
    CREATE SEQUENCE seq_test;
    SELECT NEXT VALUE FOR seq_test;
    CREATE TABLE t1(id INT IDENTITY(1,1), name VARCHAR(20));
    
  • MySQL

    1
    2
    3
    
    CREATE SEQUENCE seq_test;
    SELECT LAST_INSERT_ID();
    CREATE TABLE t1(id INT AUTO_INCREMENT, name VARCHAR(20));
    

十三、批量插入与合并

函数功能OracleSQL ServerMySQL参数说明版本要求
批量插入INSERT ALL ... / INSERT INTO ... SELECT ...INSERT INTO ... SELECT ...INSERT INTO ... SELECT ...批量插入多行数据11g+
合并(UPSERT)MERGE INTO ... USING ... ON ... WHEN MATCHED THEN ...同左MERGE INTO ... ON ... WHEN MATCHED THEN ...两者均支持标准MERGE语法11g+

SQL示例对照

13. 批量插入与合并

  • Oracle

    1
    2
    3
    4
    5
    6
    7
    
    INSERT ALL
      INTO t1 VALUES(1, 'A')
      INTO t1 VALUES(2, 'B')
    SELECT * FROM dual;
    MERGE INTO t1 USING t2 ON (t1.id = t2.id)
      WHEN MATCHED THEN UPDATE SET t1.name = t2.name
      WHEN NOT MATCHED THEN INSERT (id, name) VALUES (t2.id, t2.name);
    
  • SQL Server

    1
    2
    3
    4
    
    INSERT INTO t1 (id, name) SELECT 1, 'A' UNION ALL SELECT 2, 'B';
    MERGE t1 USING t2 ON t1.id = t2.id
      WHEN MATCHED THEN UPDATE SET t1.name = t2.name
      WHEN NOT MATCHED THEN INSERT (id, name) VALUES (t2.id, t2.name);
    
  • MySQL

    1
    2
    3
    4
    
    INSERT INTO t1 (id, name) VALUES (1, 'A'), (2, 'B');
    MERGE t1 USING t2 ON t1.id = t2.id
      WHEN MATCHED THEN UPDATE SET t1.name = t2.name
      WHEN NOT MATCHED THEN INSERT (id, name) VALUES (t2.id, t2.name);
    

十四、其它常用系统函数

函数功能OracleSQL ServerMySQL参数说明版本要求
获取服务器时间SYSDATE / SYSTIMESTAMPGETDATE() / SYSDATETIME()NOW()精度略有差异11g+
获取当前用户USER / SYS_CONTEXT('USERENV','SESSION_USER')CURRENT_USER / SUSER_SNAME()CURRENT_USER()获取当前登录用户11g+
获取主机名SYS_CONTEXT('USERENV','HOST')HOST_NAME()@@SERVERNAME获取主机名11g+

SQL示例对照

14. 其它常用系统函数

  • Oracle

    1
    
    SELECT SYSDATE, USER, SYS_CONTEXT('USERENV','HOST') FROM dual;
    
  • SQL Server

    1
    
    SELECT GETDATE(), CURRENT_USER, HOST_NAME();
    
  • MySQL

    1
    
    SELECT NOW(), CURRENT_USER, @@SERVERNAME;
    

十五、典型SQL语法差异补充

  1. LIMIT/OFFSET分页
    • Oracle 12c+:SELECT ... OFFSET N ROWS FETCH NEXT M ROWS ONLY
    • SQL Server 2012+:同上,老版本用ROW_NUMBER()子查询分页 | 11g+ |
  2. dual表
    • Oracle:SELECT 1 FROM dual
    • SQL Server:SELECT 1(无需dual) | 11g+ |
  3. 字符串转义
    • Oracle:单引号用''
    • SQL Server:同上,但部分场景支持N'...'表示Unicode | 11g+ |
  4. 布尔类型
    • Oracle无布尔类型,常用NUMBER(1)CHAR(1)
    • SQL Server有BIT类型 | 11g+ |
  5. 注释
    • 单行:--
    • 多行:/* ... */
    • 两者通用 | 11g+ |

十六、特殊函数与高级用法补充

函数功能OracleSQL ServerMySQL参数说明版本要求
分组统计GROUP BY ROLLUP/CUBEGROUP BY ROLLUP/CUBEGROUP BY WITH ROLLUP多维分组统计11g+
字符查找INSTR(str, substr)CHARINDEX(substr, str)INSTR(str, substr)返回子串位置11g+
正则匹配REGEXP_LIKE(str, pattern)LIKE/PATINDEXREGEXP_LIKE(str, pattern)/REGEXPMySQL 8+支持标准正则11g+
批量更新MERGE/UPDATE ... WHERE ...MERGE/UPDATE ... FROM ...UPDATE ... JOIN ...多表批量更新11g+
加密解密DBMS_CRYPTOENCRYPTBYPASSPHRASEAES_ENCRYPT/AES_DECRYPT内置加密函数11g+
XML处理XMLTYPE/EXTRACTVALUEFOR XML PATHExtractValue/XPath结构化数据处理11g+
JSON处理JSON_VALUE/JSON_TABLEJSON_VALUE/OPENJSONJSON_EXTRACT/JSON_TABLE结构化数据处理11g+
全文检索CONTAINSCONTAINSMATCH ... AGAINST需建全文索引11g+
随机数DBMS_RANDOM.VALUERAND()RAND()生成0-1随机数11g+
UUIDSYS_GUID()NEWID()UUID()生成唯一标识符11g+

特殊函数SQL示例

  • 分组统计

    • Oracle:

      1
      
      SELECT deptno, SUM(sal) FROM emp GROUP BY ROLLUP(deptno);
      
    • SQL Server:

      1
      
      SELECT deptno, SUM(sal) FROM emp GROUP BY ROLLUP(deptno);
      
    • MySQL:

      1
      
      SELECT deptno, SUM(sal) FROM emp GROUP BY deptno WITH ROLLUP;
      
  • 正则匹配

    • Oracle:

      1
      
      SELECT * FROM t WHERE REGEXP_LIKE(name, '^A.*');
      
    • SQL Server:

      1
      
      SELECT * FROM t WHERE name LIKE 'A%';
      
    • MySQL:

      1
      
      SELECT * FROM t WHERE name REGEXP '^A.*';
      
  • 批量更新

    • Oracle:

      1
      
      MERGE INTO t1 USING t2 ON (t1.id = t2.id) WHEN MATCHED THEN UPDATE SET t1.name = t2.name;
      
    • SQL Server:

      1
      
      UPDATE t1 SET t1.name = t2.name FROM t1 JOIN t2 ON t1.id = t2.id;
      
    • MySQL:

      1
      
      UPDATE t1 JOIN t2 ON t1.id = t2.id SET t1.name = t2.name;
      
  • 加密解密

    • Oracle:

      1
      
      SELECT RAWTOHEX(DBMS_CRYPTO.ENCRYPT(UTL_I18N.STRING_TO_RAW('abc','AL32UTF8'), 4353, UTL_I18N.STRING_TO_RAW('key','AL32UTF8')) ) FROM dual;
      
    • SQL Server:

      1
      
      SELECT ENCRYPTBYPASSPHRASE('key', 'abc');
      
    • MySQL:

      1
      
      SELECT AES_ENCRYPT('abc', 'key');
      
  • UUID

    • Oracle:

      1
      
      SELECT SYS_GUID() FROM dual;
      
    • SQL Server:

      1
      
      SELECT NEWID();
      
    • MySQL:

      1
      
      SELECT UUID();
      

十七、三大数据库特有函数及特殊场景用法

场景/功能Oracle特有SQL Server特有MySQL特有说明版本要求
分析函数扩展RATIO_TO_REPORT(expr) OVER(...)NTILE(n) OVER(...)GROUP_CONCAT(expr)Oracle支持分布占比,SQL Server分桶,MySQL字符串聚合11g+
层次查询CONNECT BY PRIORCTE递归(WITH ... AS ...)WITH RECURSIVE ...层级树结构遍历11g+
行转列PIVOT/UNPIVOTPIVOT/UNPIVOTGROUP_CONCAT+CASE WHEN交叉报表、动态列11g+
伪列ROWNUM/ROWID/LEVEL%%physloc%%/$IDENTITYROW_NUMBER()伪列/物理定位11g+
序列号SYS_GUID()NEWSEQUENTIALID()UUID_SHORT()唯一标识生成12c+
XML处理XMLTYPE/EXTRACTVALUEFOR XML PATHExtractValue/XPath结构化数据处理11g+
分区表管理DBMS_PARTSWITCH PARTITIONPARTITION BY分区表相关管理11g+
空间分析SDO_GEOMgeometry::STBuffer()ST_Buffer()GIS空间分析11g+
计划/执行分析EXPLAIN PLAN FOR ...SET SHOWPLAN_ALL ONEXPLAINSQL执行计划11g+
触发器扩展AFTER EACH ROWINSTEAD OFBEFORE/AFTER触发器细粒度控制11g+
其他DBMS_OUTPUT.PUT_LINEPRINTSELECT '...'控制台输出11g+

特有函数与特殊场景SQL示例

  • Oracle

    • 分布占比:

      1
      
      SELECT deptno, sal, RATIO_TO_REPORT(sal) OVER(PARTITION BY deptno) AS sal_ratio FROM emp;
      
    • 层次查询:

      1
      
      SELECT empno, ename, mgr FROM emp CONNECT BY PRIOR empno = mgr START WITH mgr IS NULL;
      
    • 伪列:

      1
      2
      
      SELECT ROWNUM, emp.* FROM emp;
      SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
      
    • 控制台输出:

      1
      
      BEGIN DBMS_OUTPUT.PUT_LINE('Hello Oracle!'); END;
      
  • SQL Server

    • 分桶:

      1
      
      SELECT Name, Salary, NTILE(4) OVER(ORDER BY Salary) AS Quartile FROM Employees;
      
    • 递归CTE:

      1
      2
      3
      4
      5
      
      WITH OrgChart AS (
        SELECT empid, mgrid FROM emp WHERE mgrid IS NULL
        UNION ALL
        SELECT e.empid, e.mgrid FROM emp e JOIN OrgChart o ON e.mgrid = o.empid
      ) SELECT * FROM OrgChart;
      
    • 新顺序GUID:

      1
      
      SELECT NEWSEQUENTIALID();
      
    • 控制台输出:

      1
      
      PRINT 'Hello SQL Server!';
      
  • MySQL

    • 字符串聚合:

      1
      
      SELECT GROUP_CONCAT(name ORDER BY id) FROM users;
      
    • 递归查询:

      1
      2
      3
      4
      5
      
      WITH RECURSIVE cte AS (
        SELECT id, parent_id FROM tree WHERE parent_id IS NULL
        UNION ALL
        SELECT t.id, t.parent_id FROM tree t JOIN cte ON t.parent_id = cte.id
      ) SELECT * FROM cte;
      
    • 短UUID:

      1
      
      SELECT UUID_SHORT();
      
    • 控制台输出:

      1
      
      SELECT 'Hello MySQL!';
      

十八、数据类型对照表

逻辑类型OracleSQL ServerMySQL说明
字符串VARCHAR2(n), CHAR(n), CLOBVARCHAR(n), NVARCHAR(n), TEXTVARCHAR(n), CHAR(n), TEXT长文本类型命名不同
数值NUMBER(p,s), INTEGERINT, BIGINT, DECIMAL(p,s)INT, BIGINT, DECIMAL(p,s)精度和范围略有差异
浮点BINARY_FLOAT, BINARY_DOUBLEFLOAT, REALFLOAT, DOUBLE
日期/时间DATE, TIMESTAMPDATETIME, DATE, TIMEDATETIME, DATE, TIME, TIMESTAMPOracle无TIME类型
布尔无(NUMBER(1)或CHAR(1)代替)BITTINYINT(1), BOOL
二进制BLOB, RAWVARBINARY, IMAGEBLOB, BINARY
JSON无(CLOB/JSON字段)NVARCHAR+约束/JSONJSONMySQL原生支持JSON

十九、迁移注意事项与常见问题

  1. NULL处理差异:Oracle的空字符串视为NULL,MySQL区分空字符串和NULL。
  2. 分页语法:MySQL 8.0+、SQL Server 2012+、Oracle 12c+支持标准OFFSET/FETCH,老版本需ROWNUM/ROW_NUMBER等。
  3. 布尔类型:Oracle无原生布尔,需用NUMBER(1)或CHAR(1);MySQL用TINYINT(1)。
  4. 字符串截断:SQL Server超长字符串需手动截断,Oracle可用SUBSTR。
  5. 时区/日期精度:Oracle的TIMESTAMP精度高,MySQL默认无时区。
  6. 函数参数顺序:如SUBSTR/substring参数顺序不同。
  7. 正则表达式:MySQL 8.0+支持标准正则,SQL Server仅LIKE/PATINDEX。
  8. 唯一约束/自增:Oracle 12c+支持IDENTITY,MySQL用AUTO_INCREMENT,SQL Server用IDENTITY。
  9. 批量插入/合并:Oracle支持INSERT ALL,MySQL用多VALUES,SQL Server用MERGE。
  10. 分区表/空间数据:三库分区和空间类型实现差异大,需单独迁移设计。

二十、性能优化建议

  • 尽量使用索引字段做条件,避免全表扫描。
  • 聚合/窗口函数大表上建议分批处理或加索引。
  • 批量DML建议分批提交,防止锁表。
  • 字符串聚合、JSON处理等大数据量下建议评估执行计划。
  • 合理使用分区表、分区索引提升大表查询性能。
  • 避免在WHERE子句中对字段做函数运算。

二十一、DDL/DML迁移脚本模板

  • 表结构迁移

    • Oracle:

      1
      2
      3
      4
      5
      
      CREATE TABLE t1 (
        id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name VARCHAR2(50),
        created_at DATE
      );
      
    • SQL Server:

      1
      2
      3
      4
      5
      
      CREATE TABLE t1 (
        id INT IDENTITY(1,1) PRIMARY KEY,
        name VARCHAR(50),
        created_at DATETIME
      );
      
    • MySQL:

      1
      2
      3
      4
      5
      
      CREATE TABLE t1 (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50),
        created_at DATETIME
      );
      
  • 索引迁移

    • Oracle:CREATE INDEX idx_name ON t1(name);
    • SQL Server/MySQL:CREATE INDEX idx_name ON t1(name);
  • 视图迁移

    • Oracle/SQL Server/MySQL:CREATE VIEW v1 AS SELECT ... FROM ...;
  • 存储过程/函数迁移:建议逐条分析,语法差异较大。


二十二、迁移后测试与验证建议

  • 数据量校验

    1
    
    SELECT COUNT(*) FROM t1;
    
  • 聚合校验

    1
    
    SELECT SUM(amount), AVG(amount) FROM t1;
    
  • 样本数据对比

    1
    
    SELECT * FROM t1 WHERE id IN (1,2,3);
    
  • 主键/唯一约束校验

    1
    
    SELECT id, COUNT(*) FROM t1 GROUP BY id HAVING COUNT(*) > 1;
    
  • NULL/空值校验

    1
    
    SELECT COUNT(*) FROM t1 WHERE col IS NULL;
    
  • 性能对比

    • 使用EXPLAIN/EXPLAIN PLAN/SHOWPLAN等分析SQL执行计划。