專案需將資料庫從 MySQL 遷移至 Oracle 時,單純匯入資料遠遠不夠,SQL 語法、函數、保留字、分頁寫法等差異會導致應用程式大量報錯。本文整理最常踩的坑與對照表,助您順利完成遷移。
| 功能 | MySQL | Oracle | 備註 |
|---|---|---|---|
| 分頁查詢 | LIMIT offset, pageSize | 子查詢 + ROWNUM / ROW_NUMBER() OVER() (12c+) | Oracle 需雙層子查詢控制範圍 |
| 日期格式化 | DATE_FORMAT(date, '%Y-%m-%d') | TO_CHAR(date, 'YYYY-MM-DD') | 格式字串大小寫敏感 |
| 取得目前時間 | NOW() / SYSDATE() | SYSDATE / CURRENT_TIMESTAMP | Oracle SYSDATE 無括號 |
| 字串串接 | CONCAT() / || (需 PIPES_AS_CONCAT) | || | MySQL 預設 || 為邏輯 OR |
| 自動遞增欄位 | AUTO_INCREMENT | SEQUENCE + Trigger / GENERATED AS IDENTITY (12c+) | 架構差異大 |
| 保留字衝突 | type, order, group 等非保留字 | 上述皆為保留字 | Oracle 需雙引號 "TYPE" 或改名 |
| 大小寫敏感 | 預設不敏感 (視 Collation) | 預設敏感 (識別字轉大寫) | 建議統一使用大寫識別字 |
| 空字串 vs NULL | '' != NULL | '' IS NULL | Oracle 視空字串為 NULL |
-- MySQL
SELECT * FROM orders ORDER BY id DESC LIMIT 20, 10;
-- Oracle 11g/12c 通用寫法
SELECT * FROM (
SELECT a.*, ROWNUM rn FROM (
SELECT * FROM orders ORDER BY id DESC
) a WHERE ROWNUM <= 30
) WHERE rn > 20;
-- Oracle 12c+ 標準語法
SELECT * FROM orders ORDER BY id DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
-- MySQL
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND DATE_FORMAT(create_time, '%Y-%m-%d') = '2023-01-01'
-- Oracle
WHERE create_time >= SYSDATE - 7
AND TO_CHAR(create_time, 'YYYY-MM-DD') = '2023-01-01'
-- MySQL: type 可直接做欄位名
CREATE TABLE t (id INT, type VARCHAR(20));
-- Oracle: 必須雙引號 (且大小寫敏感)
CREATE TABLE t (id NUMBER, "TYPE" VARCHAR2(20));
-- 查詢時也要加雙引號
SELECT "TYPE" FROM t;
LIMIT、NOW()、DATE_FORMAT、AUTO_INCREMENT 等 MySQL 專有語法工具推薦: 可使用 SQLines、Ora2Pg、AWS SCT 等自動化遷移工具輔助轉換,但人工審核測試不可省略。