首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 與 Oracle 語法差異全景對比:開發遷移必備參考手冊

     編輯:MySQL 資料庫相關知識

MySQL 與 Oracle 在 SQL 方言、數據類型、函數、存儲過程、事務控制等方面存在顯著差異。本文從實戰遷移角度,系統對比 18 大核心差異點,提供對照表與改寫模式,助力異構數據庫遷移與多數據庫兼容開發。

核心差異對照表

類別OracleMySQL改寫要點
日期時間SYSDATENOW() / SYSDATE()MySQL SYSDATE() 為動態值,NOW() 為語句開始時固定值
TO_CHAR(date, 'fmt')DATE_FORMAT(date, '%fmt')格式符不同:YYYY→%Y, MM→%m, DD→%d, HH24→%H, MI→%i, SS→%s
ADD_MONTHS(d, n)DATE_ADD(d, INTERVAL n MONTH)MySQL INTERVAL 關鍵字靈活支持 YEAR/QUARTER/MONTH/DAY/HOUR/MINUTE/SECOND
字符串|| 拼接CONCAT(str1, str2, ...)MySQL || 為邏輯 OR(除非開啟 PIPES_AS_CONCAT SQL 模式)
SUBSTR(str, pos, len)SUBSTRING(str, pos, len) / MID()MySQL 位置從 1 起算,支持負數倒數;Oracle 同
NVL(expr1, expr2)IFNULL(expr1, expr2) / COALESCE()COALESCE 為標準 SQL,多參數優先用它
分頁/限制ROWNUM 偽列LIMIT offset, countOracle 需子查詢包裹 WHERE rn BETWEEN a AND b;MySQL 直觀
FETCH FIRST n ROWS ONLY (12c+)LIMIT n標準 SQL 寫法 Oracle 12c+ 支持,MySQL 8.0.21+ 亦支持
變量聲明DECLARE v INT; v := 1;SET @v = 1; (用戶變量)
DECLARE v INT DEFAULT 1; (存儲過程局部變量,無 @)
MySQL 用戶變量 @var 跨會話可見(同連接),局部變量無 @ 且需在 BEGIN...END 內聲明
存儲過程CREATE PROCEDURE p(p1 IN INT) AS BEGIN ... END;CREATE PROCEDURE p(IN p1 INT) BEGIN ... ENDMySQL 需 DELIMITER // 修改結束符;參數模式 IN/OUT/INOUT 關鍵字前置
游標隱式屬性 %NOTFOUNDDECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;MySQL 無隱式游標屬性,必須用 Handler 捕獲 NOT FOUND 異常
GROUP BY嚴格模式:SELECT 列必須出現在 GROUP BY 或聚合函數中默認非嚴格:允許選取未分組列(取組內第一行),ONLY_FULL_GROUP_BY 開啟後一致遷移時建議開啟 ONLY_FULL_GROUP_BY 確保語義正確
條件表達式DECODE(expr, search, result, ...)CASE WHEN ... THEN ... ELSE ... ENDMySQL 不支持 DECODE,統一用標準 CASE
類型轉換TO_NUMBER, TO_DATECAST(expr AS TYPE), CONVERT(expr, TYPE)MySQL CAST(... AS SIGNED/UNSIGNED/DECIMAL/DATE/DATETIME/CHAR)
自增/序列SEQUENCE / SEQ.NEXTVALAUTO_INCREMENT 列MySQL 插入後獲取 ID:LAST_INSERT_ID() / JDBC getGeneratedKeys()
唯一標識SYS_GUID() (RAW 16字節)UUID() (VARCHAR 36字節)MySQL 8.0 UUID_TO_BIN()/BIN_TO_UUID() 可存為 BINARY(16) 節省空間
空值排序ORDER BY col NULLS FIRST/LASTORDER BY IS NULL(col), col (模擬)MySQL 8.0.2+ 支持 NULLS FIRST/LAST 語法
合併查詢MINUS (差集)EXCEPT (8.0.31+)舊版用 LEFT JOIN ... WHERE IS NULL 或 NOT IN/EXISTS 模擬
雙表更新UPDATE (SELECT ... FROM a JOIN b) SET ...UPDATE a JOIN b ON ... SET a.col = b.col WHERE ...MySQL 支持多表 UPDATE/JOIN 語法,更直觀

存儲過程遷移關鍵點

-- Oracle
CREATE OR REPLACE PROCEDURE proc_demo (p_id IN NUMBER, p_result OUT VARCHAR2) AS
BEGIN
  SELECT name INTO p_result FROM t WHERE id = p_id;
EXCEPTION
  WHEN NO_DATA_FOUND THEN p_result := 'NOT_FOUND';
END;

-- MySQL
DELIMITER //
CREATE PROCEDURE proc_demo (IN p_id INT, OUT p_result VARCHAR(100))
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE v_name VARCHAR(100);
  DECLARE cur CURSOR FOR SELECT name FROM t WHERE id = p_id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  
  OPEN cur;
  FETCH cur INTO v_name;
  IF done = 1 THEN
    SET p_result = 'NOT_FOUND';
  ELSE
    SET p_result = v_name;
  END IF;
  CLOSE cur;
END //
DELIMITER ;

核心差異:異常處理 → Handler + 狀態變量、游標必須顯式 OPEN/FETCH/CLOSE、變量聲明區分 @用戶變量 與 無@局部變量。

遷移工具與驗證建議

  • SQL Developer / MySQL Workbench 內建遷移嚮導(Schema、數據、代碼對象)。
  • ora2pg:開源 Perl 工具,支持 Oracle → PostgreSQL/MySQL 結構與數據遷移。
  • SQL 兼容模式:MySQL SET sql_mode='ORACLE'(8.0.31+ 實驗性)可部分兼容 ||、ROWNUM、NVL 等語法,但不建議生產依賴,應徹底改寫。
  • 回歸測試:建立對比測試集,對比兩庫相同業務邏輯的結果集、執行計劃、效能指標。

總結

MySQL 與 Oracle 差異本質上源於架構哲學不同:Oracle 重企業級特性、複雜 PL/SQL、共享池;MySQL 重輕量、標準 SQL 合規、存儲引擎插件化。遷移核心策略:Schema 結構對標、業務邏輯下沉應用層、存儲過程重寫為應用代碼、利用中間件(ShardingSphere/Seata)彌補分布式事務能力。本文對照表可作為遷移項目「核對清單」逐項驗收。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved