Oracle 與 SQL Server (T-SQL) 在函數命名、參數順序、回傳型別上存在顯著差異。本文整理 4 大類 23 項高頻函數對照,涵蓋數學、字串、日期、轉換/條件,並標註參數差異與遷移陷阱,作為開發遷移、跨平台 SQL 撰寫的桌邊速查表。
| 功能 | SQL Server (T-SQL) | Oracle | 備註/遷移提示 |
|---|---|---|---|
| 絕對值 | ABS(-1) | ABS(-1) | 語法相同 |
| 向上取整 (Ceiling) | CEILING(-1.001) → 0 | CEIL(-1.001) → 0 | Oracle 縮寫 CEIL |
| 向下取整 (Floor) | FLOOR(-1.001) → -2 | FLOOR(-1.001) → -2 | 語法相同 |
| 截取整數 (Truncate) | CAST(-1.002 AS INT) → -1 | TRUNC(-1.002) → -1 | Oracle TRUNC 可指定小數位 TRUNC(1.234,2)=1.23 |
| 四捨五入 | ROUND(1.23456,4) → 1.2346 | ROUND(1.23456,4) → 1.2346 | 語法相同,Oracle 第 2 參數可負數 (十位、百位) |
| e 的冪次 | EXP(1) → 2.71828... | EXP(1) → 2.71828... | 相同 |
| 自然對數 (ln) | LOG(2.71828...) → 1 | LN(2.71828...) → 1 | SQL Server LOG 為自然對數,Oracle 用 LN |
| 以 10 為底對數 | LOG10(10) → 1 | LOG(10,10) → 1 | Oracle LOG(base, value) 參數順序反轉 |
| 平方 | SQUARE(4) → 16 | POWER(4,2) → 16 | Oracle 通用 POWER |
| 平方根 | SQRT(4) → 2 | SQRT(4) → 2 | 相同 |
| 任意冪次 | POWER(3,4) → 81 | POWER(3,4) → 81 | 相同 |
| 隨機數 | RAND() → 0~1 | DBMS_RANDOM.VALUE(0,1) | Oracle 需呼叫 PL/SQL 套件,可指定範圍 |
| 正負號 | SIGN(-8) → -1 | SIGN(-8) → -1 | 相同 |
| 圓周率 π | PI() → 3.14159... | 無內建 | Oracle 自定義 ACOS(-1) 或常數 3.14159265358979323846 |
| 三角函數 (sin/cos/tan) | 參數為弧度 | 參數為弧度 | 相同,角度轉弧度 RADIANS() (SQL Server) / *ACOS(-1)/180 (Oracle) |
| 反三角函數 | ASIN/ACOS/ATAN/ATN2 → 弧度 | ASIN/ACOS/ATAN/ATAN2 → 弧度 | Oracle ATAN2(y,x) 參數順序 y,x |
| 角度/弧度互轉 | DEGREES(rad), RADIANS(deg) | 無內建 | Oracle 自行計算:deg * ACOS(-1)/180 |
| 功能 | SQL Server | Oracle | 備註 |
|---|---|---|---|
| 字串連接 | '11' + '22' + '33' → '112233' | CONCAT('11','22') || '33' 或 '11' || '22' || '33' | Oracle || 為標準連接運算子,CONCAT 僅兩參數 |
| 子字串 | SUBSTRING(str, start, len) | SUBSTR(str, start, len) | 參數順序相同,Oracle start 可負數 (從尾部倒數) |
| 字串長度 | LEN(str) (不含尾部空格) | LENGTH(str) / LENGTHB(str) (位元組) | SQL Server DATALENGTH 為位元組長度 |
| 大小寫轉換 | UPPER/LOWER | UPPER/LOWER | 相同 |
| 去除空格 | LTRIM/RTRIM/TRIM | LTRIM/RTRIM/TRIM | Oracle TRIM 可指定字元 TRIM('x' FROM str) |
| 字串替換 | REPLACE(str, old, new) | REPLACE(str, old, new) | 相同 |
| 字元編碼 | ASCII('a') → 97 | ASCII('a') → 97 | 相同 |
| 編碼轉字元 | CHAR(97) → 'a' | CHR(97) → 'a' | Oracle 用 CHR |
| 字串查找位置 | CHARINDEX('sub', str) | INSTR(str, 'sub') | Oracle INSTR 支援第 N 次出現、反向搜尋 |
| 左/右取字串 | LEFT(str, n), RIGHT(str, n) | SUBSTR(str, 1, n), SUBSTR(str, -n) | Oracle 用 SUBSTR 通用 |
| 功能 | SQL Server | Oracle | 關鍵差異 |
|---|---|---|---|
| 當前日期時間 | GETDATE() / SYSDATETIME() | SYSDATE / SYSTIMESTAMP | Oracle SYSDATE 精確至秒,SYSTIMESTAMP 含毫秒/時區 |
| 日期加減 | DATEADD(day, 10, dt) | dt + 10 (數字代表天) / dt + INTERVAL '10' DAY | Oracle 數字直接加減天,INTERVAL 支援年/月/日/時/分/秒 |
| 日期差值 | DATEDIFF(day, dt1, dt2) | dt2 - dt1 (結果為天數含小數) | Oracle 相減直接得天數,需 TRUNC 取整 |
| 日期截取 | CAST(dt AS DATE) | TRUNC(dt) / TRUNC(dt, 'MM') | Oracle TRUNC 強大,可截至年/月/日/週/時/分 |
| 日期格式化 | FORMAT(dt, 'yyyy-MM-dd') (2012+) | TO_CHAR(dt, 'YYYY-MM-DD') | Oracle 格式模型豐富 (FM、FX、SP、TH 等) |
| 字串轉日期 | CAST('2023-01-01' AS DATE) / CONVERT | TO_DATE('2023-01-01', 'YYYY-MM-DD') | Oracle 必須指定格式模型,NLS_DATE_FORMAT 影響隱性轉換 |
| 日期元件擷取 | YEAR(dt), MONTH(dt), DAY(dt) | EXTRACT(YEAR FROM dt), TO_CHAR(dt, 'MM') | Oracle 標準 EXTRACT 或 TO_CHAR |
| 月份最後一天 | EOMONTH(dt) (2012+) | LAST_DAY(dt) | 相同功能 |
| 下一個工作日 | 無內建 | NEXT_DAY(dt, 'FRIDAY') | Oracle 特有 |
| 兩日期間月數 | DATEDIFF(month, dt1, dt2) | MONTHS_BETWEEN(dt1, dt2) | Oracle 結果含小數 |
| 功能 | SQL Server | Oracle | 備註 |
|---|---|---|---|
| NULL 替換 | ISNULL(col, default_val) | NVL(col, default_val) | Oracle NVL2(col, not_null_val, null_val) 三參數版 |
| 多值首個非 NULL | COALESCE(a,b,c) | COALESCE(a,b,c) | ANSI 標準,相同 |
| 條件表達式 (CASE) | CASE WHEN cond THEN v1 ELSE v2 END | CASE WHEN cond THEN v1 ELSE v2 END | 相同,Oracle 另支援 DECODE(col, val1, res1, val2, res2, default) |
| 最大值 (標量) | MAX(val) OVER (...) 或子查詢 | GREATEST(a,b,c) | Oracle GREATEST/LEAST 為標量函數,非彙總 |
| 最小值 (標量) | 子查詢 | LEAST(a,b,c) | 同上 |
| 型別轉換 | CAST(expr AS TYPE), CONVERT(TYPE, expr) | CAST(expr AS TYPE), TO_CHAR/TO_NUMBER/TO_DATE | Oracle 專用格式化轉換函數更強 |
CAST/TO_CHAR/TO_NUMBER/TO_DATE,避免 ORA-01722/ORA-018xx。SYSDATE **精度陷阱**:Oracle SYSDATE 無毫秒,高併發主鍵生成勿用 TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS'),改用 SYSTIMESTAMP + SEQ 或 SYS_GUID()。RR/RRRR (兩位年自動推斷世紀) vs YY/YYYY,遷移時統一用 YYYY 避免 2000 年問題。'A' || NULL = 'A',SQL Server 'A' + NULL = NULL (除非 SET CONCAT_NULL_YIELDS_NULL OFF)。遷移需用 NVL(col,'') 或 COALESCE 統一語義。LEVEL, UID, COMMENT),遷移時雙引號包裹或改名。函數對照是遷移第一步,真正挑戰在於語義等價:NULL 處理、日期精度、隱性轉換、排序規則、鎖行為。建議建立「函數映射標準庫」+「自動化改寫腳本」+「回歸測試資料集」,將人工修正降至最低。