MySQL与Oracle的SQL语法差异

Published on with 0 views and 0 comments

MySQL和Oracle虽然都遵循SQL标准,但在具体语法上存在不少差异。以下是主要的语法区别:

1. 分页查询

  • MySQL:

    SELECT * FROM table_name LIMIT 10 OFFSET 20;
    或
    SELECT * FROM table_name LIMIT 20, 10;
    
  • Oracle:

    -- 12c以下版本
    SELECT * FROM (
      SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM table_name ORDER BY column_name
      ) a WHERE ROWNUM <= 30
    ) WHERE rn > 20;
    
    -- 12c及以上版本
    SELECT * FROM table_name OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
    

2. 字符串连接

  • MySQL:

    SELECT CONCAT('Hello', ' ', 'World');
    或使用||(需设置SQL模式)
    
  • Oracle:

    SELECT 'Hello' || ' ' || 'World' FROM dual;
    

3. 日期和时间函数

  • MySQL:

    SELECT NOW();  -- 当前日期时间
    SELECT CURDATE();  -- 当前日期
    SELECT DATE_ADD(NOW(), INTERVAL 1 DAY);
    SELECT DATEDIFF('2023-12-31', '2023-01-01');
    
  • Oracle:

    SELECT SYSDATE FROM dual;  -- 当前日期时间
    SELECT CURRENT_DATE FROM dual;  -- 当前日期
    SELECT ADD_MONTHS(SYSDATE, 1) FROM dual;
    SELECT TO_DATE('2023-12-31', 'YYYY-MM-DD') - TO_DATE('2023-01-01', 'YYYY-MM-DD') FROM dual;
    

4. 空值处理

  • MySQL:

    SELECT IFNULL(column_name, 'default') FROM table_name;
    或
    SELECT COALESCE(column_name, 'default') FROM table_name;
    
  • Oracle:

    SELECT NVL(column_name, 'default') FROM table_name;
    或
    SELECT COALESCE(column_name, 'default') FROM table_name;
    

5. 自增字段

  • MySQL:

    CREATE TABLE table_name (
      id INT AUTO_INCREMENT PRIMARY KEY,
      ...
    );
    
  • Oracle:

    CREATE TABLE table_name (
      id NUMBER GENERATED ALWAYS AS IDENTITY,
      ...
    );
    
    -- 或使用序列
    CREATE SEQUENCE seq_name;
    CREATE TRIGGER trig_name BEFORE INSERT ON table_name 
    FOR EACH ROW BEGIN
      SELECT seq_name.NEXTVAL INTO :NEW.id FROM dual;
    END;
    

6. 数据类型差异

数据类型MySQLOracle
整数INT, INTEGERNUMBER(10)
字符串VARCHAR(n)VARCHAR2(n)
大文本TEXT, LONGTEXTCLOB
二进制大对象BLOB, LONGBLOBBLOB
布尔TINYINT(1)或BOOLEANNUMBER(1)

7. 系统函数差异

  • 获取当前用户:

    • MySQL: SELECT USER();
    • Oracle: SELECT USER FROM dual;
  • 条件判断:

    • MySQL: IF(condition, true_value, false_value)
    • Oracle: CASE WHEN condition THEN true_value ELSE false_value END

8. 子查询限制

  • MySQL对子查询的限制较少
  • Oracle在某些版本中对子查询有更多限制(如早期版本中FROM子句中的子查询需要别名)

9. 事务控制

  • MySQL(InnoDB引擎):

    START TRANSACTION;
    -- SQL语句
    COMMIT; 或 ROLLBACK;
    
  • Oracle:

    SET TRANSACTION;  -- 可选
    -- SQL语句
    COMMIT; 或 ROLLBACK;
    

10. 伪表

  • MySQL: 可以直接执行不带FROM的SELECT

    SELECT 1 + 1;
    
  • Oracle: 需要使用DUAL伪表

    SELECT 1 + 1 FROM dual;
    

这些差异在实际开发中需要特别注意,特别是在迁移数据库或编写跨数据库兼容的SQL时。


标题:MySQL与Oracle的SQL语法差异
作者:Tomiaocat
地址:https://books.loen.top/articles/2025/07/11/1752221931362.html