# \*\*Oracle 与 MySQL SQL 主要差别\*\* \| 场景 \| Oracle \| MySQL \| 说明 \| \| ---------------- \| ------------------------------------------------------------ \| ------------------------------------------------------ \| ------------------------------------------------------------ \| \| \*\*分页查询\*\* \| \`sql SELECT \* FROM (SELECT t.\*, ROWNUM rn FROM table t WHERE ROWNUM \<= 20) WHERE rn \> 10;\` \| \`sql SELECT \* FROM table LIMIT 10, 10;\` \| MySQL \`LIMIT offset, size\`,Oracle 用 \`ROWNUM\` 或 \`FETCH NEXT\`(12c+) \| \| \*\*字符串拼接\*\* \| \`SELECT 'Hello' \|\| ' ' \|\| 'World' AS result FROM dual;\` \| \`SELECT CONCAT(first_name, ' ', last_name) FROM emp; \` \| 两者语法符号不同,而且空值处理逻辑也不一样。 \| \| \*\*获取系统时间\*\* \| \`SELECT SYSDATE FROM dual;\` \| \`SELECT NOW();\` 或 \`SELECT CURRENT_TIMESTAMP;\` \| Oracle 有 \`dual\` 虚拟表 \| \| \*\*空字符串处理\*\* \| 空字符串当作 \`NULL\` \| 空字符串就是空字符串 \| Oracle 中 \`'' = NULL\` \| \| \*\*自动递增主键\*\* \| \`CREATE SEQUENCE seq_name;\` + \`NEXTVAL\` 获取值 \| \`AUTO_INCREMENT\` \| Oracle 12c+ 支持 \`IDENTITY\` \| \| \*\*字符串截取\*\* \| \`SUBSTR(str, start, length)\` \| \`SUBSTRING(str, start, length)\` \| 函数名不同 \| \| \*\*日期加减\*\* \| \`SYSDATE + 1\` 表示加一天 \| \`DATE_ADD(NOW(), INTERVAL 1 DAY)\` \| Oracle 日期是可直接加减数字 \| \| \*\*条件判断\*\* \| \`CASE WHEN ... THEN ... ELSE ... END\` 或 \`DECODE(expr, val, result, ...)\` \| 只支持 \`CASE WHEN ... THEN ... ELSE ... END\` \| Oracle 多了 \`DECODE()\` 简写 \| \| \*\*TOP N 查询\*\* \| \`ROWNUM \<= N\`(或 12c+ \`FETCH FIRST N ROWS ONLY\`) \| \`LIMIT N\` \| MySQL 简单很多 \| \| \*\*布尔类型\*\* \| 无原生布尔型,用 \`CHAR(1)\`/\`NUMBER(1)\` 代替 \| 有 \`BOOLEAN\`(TINYINT(1)) \| 逻辑表达不同 \| \| \*\*字符串长度\*\* \| \`LENGTH()\` 按字节,\`LENGTHB()\` 按字节长度,\`LENGTHC()\` 按字符 \| \`LENGTH()\` 按字节,\`CHAR_LENGTH()\` 按字符 \| 多字节字符时要注意 \| \| \*\*事务提交\*\* \| 默认手动提交 \| 默认自动提交 \| MySQL 需 \`SET autocommit=0;\` 才改成手动提交 \| \| \*\*正则匹配\*\* \| \`REGEXP_LIKE(col, pattern)\` \| \`col REGEXP pattern\` \| 语法差别大 \| \> Oracle 和 MySQL 在 SQL 语法上差异主要集中在\*\*分页、日期处理、字符串拼接、自动递增、空值处理\*\*等方面。迁移时要重点关注分页语句、空字符串与 NULL 的区别、以及序列/自增主键的实现方式。