遷移背景:異構平台語法適配的必修課
企業將 Oracle 業務遷移至 DB2 時,核心挑戰在於 SQL 方言差異。本文針對 7 大高頻場景,提供 Oracle 與 DB2 (以 7.x/8.x 為例) 的標準寫法對照,並補充 DB2 獨有進階語法,作為開發與遷移團隊的桌面速查卡。
1. 限制返回行數:Top-N 查詢
| 場景 | Oracle | DB2 標準寫法 | DB2 進階 (窗口函數) |
| 前 N 行 | WHERE ROWNUM <= n | FETCH FIRST n ROWS ONLY | WHERE ROW_NUMBER() OVER() <= n |
| 分頁 (M~N) | WHERE RN BETWEEN m AND n (子查詢) | OFFSET m-1 ROWS FETCH FIRST n-m+1 ROWS ONLY (DB2 11.1+) | WHERE RN BETWEEN m AND n (ROW_NUMBER) |
注意: DB2 FETCH FIRST 不支持變量,動態分頁需用 ROW_NUMBER() OVER() 或預編譯參數化。
2. 獲取當前日期時間
| Oracle | DB2 | 說明 |
SYSDATE (DATE 類型,含時分秒) | CURRENT TIMESTAMP (TIMESTAMP) | 精度不同,DB2 納秒級 |
SYSTIMESTAMP (TIMESTAMP WITH TZ) | CURRENT TIMESTAMP WITH TIME ZONE | 帶時區 |
DUAL 虛表 | SYSIBM.SYSDUMMY1 | DB2 系統虛表 |
-- Oracle
SELECT SYSDATE FROM DUAL;
-- DB2
SELECT CURRENT TIMESTAMP FROM SYSIBM.SYSDUMMY1;
3. 字符串拼接
| Oracle | DB2 | 標準 SQL |
col1 || col2 | col1 || col2 (默認啟用) | CONCAT(col1, col2) (僅兩參數) |
CONCAT(col1, col2) | CONCAT(col1, col2) | 同上 |
DB2 需確保 DB2_COMPATIBILITY_VECTOR 位 1 (ORA) 啟用,或數據庫級 SET CONCAT = '||'。
4. 查詢表結構
原文第 4 點內容有誤 (重複了日期查詢),此處補正標準做法:
| Oracle | DB2 |
DESC table_name (SQL*Plus)
SELECT * FROM USER_TAB_COLUMNS WHERE TABLE_NAME='T' | DESCRIBE TABLE schema.table (CLP)
SELECT * FROM SYSCAT.COLUMNS WHERE TABNAME='TABLE' AND TABSCHEMA='SCHEMA' |
5. 內連接 (INNER JOIN)
| Oracle (舊語法) | DB2 / ANSI SQL-92 |
SELECT a.* FROM t1 a, t2 b WHERE a.id = b.id | SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id |
強烈建議全面遷移至 ANSI JOIN 語法,可讀性與優化器提示支持更好。
6. 外連接 (LEFT/RIGHT/FULL OUTER JOIN)
| 類型 | Oracle (舊語法 +) | DB2 / ANSI 標準 |
| 左外連接 | WHERE a.id = b.id(+) | FROM a LEFT OUTER JOIN b ON a.id = b.id |
| 右外連接 | WHERE a.id(+) = b.id | FROM a RIGHT OUTER JOIN b ON a.id = b.id |
| 全外連接 | 不支持 (需 UNION) | FROM a FULL OUTER JOIN b ON a.id = b.id |
DB2 完整支持三類外連接,遷移時務必改寫為 ANSI 語法,Oracle (+) 標記在 DB2 無效並報錯。
7. 執行腳本文件
| Oracle (SQL*Plus) | DB2 (CLP) |
@$PATH/file.sql 或 START $PATH/file.sql | db2 -tvf $PATH/file.sql |
-t : 以分號 ; 為語句終止符
-v : 回顯命令文本
-f : 指定輸入文件
- 腳本內每句必須以 分號結尾
補充:遷移高頻差異擴展包
| 類別 | Oracle | DB2 等效 | 備註 |
| 空值判斷 | NVL(col, def) | COALESCE(col, def) / IFNULL(col, def) | COALESCE 多參數、標準 SQL |
| 條件表達式 | DECODE / CASE | CASE (不支持 DECODE) | CASE 功能更強 |
| 日期運算 | SYSDATE + 1 | CURRENT DATE + 1 DAY | DB2 使用標籤間隔 |
| 序列/自增 | SEQUENCE / TRIGGER | IDENTITY / SEQUENCE | DB2 9.7+ 原生 SEQUENCE |
| 臨時表 | GLOBAL TEMPORARY TABLE | DECLARE GLOBAL TEMPORARY TABLE SESSION.t ... | 會話級隔離,ON COMMIT PRESERVE/DELETE ROWS |
| MERGE | MERGE INTO ... USING ... | MERGE INTO ... USING ... | 語法一致,DB2 支持更豐富 WHEN 子句 |
| 分析函數 | ROW_NUMBER, RANK, LAG/LEAD | 完全兼容 | 窗口函數語法一致 |
遷移工具鏈推薦
- IBM Data Movement Tool / MTK (Migration Toolkit): 自動評估、語法轉換、數據遷移一站式
- SQLines / Ora2Pg (開源): 輕量級腳本轉換
- DB2_EXPLAIN + db2look: 驗證執行計劃一致性、導出 DDL
結語
語法遷移只是第一步,真正挑戰在於:優化器行為差異 (直方圖/統計信息)、並發控制 (鎖升級/死鎖檢測)、PL/SQL → SQL PL 過程邏輯重寫、外部依賴 (DB Link/Job/Queue) 替代。建議建立「語法對照表 → 單元測試覆蓋 → 性能基線對比 → 灰度驗證」四階段遷移交付標準。