MySQL 與 Oracle 存儲過程語法差異速查表
遷移或雙寫存儲過程時,語法差異是最大阻力。本文將核心差異整理為對照表,便於快速查閱與轉換。
1. 條件語句
| 特性 | Oracle | MySQL |
| ELSE IF 關鍵字 | ELSIF | ELSEIF |
| 結束標記 | END IF; | END IF; |
2. 字符串連接
| 操作 | Oracle | MySQL |
| 連接運算符 | || | CONCAT(str1, str2, ...) |
3. 日期計算
| 需求 | Oracle | MySQL |
| 當前時間 | SYSDATE | SYSDATE() / NOW() |
| 字符 → 日期 | TO_DATE(str, fmt) | STR_TO_DATE(str, fmt) |
| 日期 → 字符 | TO_CHAR(date, fmt) | DATE_FORMAT(date, fmt) |
| 數字 → 字符 | TO_CHAR(num) | CONCAT(num, '') / CAST(num AS CHAR) |
| 間隔月份 | MONTHS_BETWEEN(d1,d2) | TIMESTAMPDIFF(MONTH, d1, d2) |
| 間隔天數 | d1 - d2 | DATEDIFF(d1, d2) |
| 單位關鍵字 | — | SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTER,YEAR |
4. 游標定義
| 階段 | Oracle | MySQL |
| 聲明 | CURSOR cur_name IS SELECT ...; | DECLARE cur_name CURSOR FOR SELECT ...; |
| 打開 | OPEN cur_name; | OPEN cur_name; |
| 取值 | FETCH cur_name INTO var1, var2; | FETCH cur_name INTO var1, var2; |
| 關閉 | CLOSE cur_name; | CLOSE cur_name; |
5. SELECT INTO 賦值與異常處理
| 場景 | Oracle | MySQL |
| 無數據異常 | EXCEPTION WHEN NO_DATA_FOUND THEN ... | 無異常機制,SELECT ... INTO 不報錯,變量保持原值,**需手工重置**並加 LIMIT 1 |
| 多行異常 | WHEN TOO_MANY_ROWS | 同樣不報錯,只取第一行,**務必加 LIMIT 1** |
6. 其他高頻差異
- 變量聲明:Oracle 在
DECLARE 段;MySQL 用 DECLARE var TYPE [DEFAULT val]; 在 BEGIN 內。
- 分隔符:MySQL 需
DELIMITER // 修改語句結束符,Oracle 用 / 或 ;。
- 流程控制:MySQL 有
LOOP、REPEAT、WHILE、ITERATE、LEAVE;Oracle 用 LOOP ... EXIT WHEN。
- 錯誤處理:Oracle
EXCEPTION 塊完善;MySQL 5.7+ 始支持 DECLARE ... HANDLER,功能較弱。
- 調用方式:Oracle
CALL proc(); 或 EXEC proc;;MySQL 僅 CALL proc();。
遷移建議清單
- 全量替換
|| → CONCAT()。
ELSIF → ELSEIF。
- 日期函數對照表逐行轉換。
- 游標聲明語法調整。
- 重點:所有
SELECT INTO 後補充 IF var IS NULL THEN SET var = ''; END IF; 並加 LIMIT 1。
- 異常處理邏輯改寫為
IF ... THEN ... ELSE ... END IF; 判斷 ROW_COUNT() 或變量狀態。
- 在目標庫跑單元測試,重點驗證邊界條件(空結果、多行、類型轉換)。
將此表收藏,雙寫存儲過程時隨時對照,效率提升 80%。