Oracle 提供三種 TIMESTAMP 型別,在毫秒精度、時區資訊攜帶、本地時間轉換行為上截然不同。本文透過建表、插資、切換 Session 時區實測,完整呈現三類型行為差異。
| 型別 | 毫秒精度 | 輸出攜帶時區 | 受 Session 時區影響 |
|---|---|---|---|
| TIMESTAMP | ✅ (0-9 位,預設 6) | ❌ | ❌ |
| TIMESTAMP WITH TIME ZONE | ✅ | ✅ (儲存時區位移) | ❌ |
| TIMESTAMP WITH LOCAL TIME ZONE | ✅ | ❌ (正規化為資料庫時區) | ✅ (查詢轉換為 Client 時區) |
CREATE TABLE timestamp_test ( dt DATE, tp TIMESTAMP(6), tp_tz TIMESTAMP(6) WITH TIME ZONE, tp_l_tz TIMESTAMP(6) WITH LOCAL TIME ZONE ); INSERT INTO timestamp_test VALUES (SYSDATE, SYSDATE, SYSDATE, SYSDATE); COMMIT; -- 資料庫時區 +00:00,Session 時區 +08:00 SELECT DBTIMEZONE, SESSIONTIMEZONE FROM DUAL; -- +00:00 | +08:00
SELECT * FROM timestamp_test; DT TP TP_TZ TP_L_TZ ----------- ------------------------------- ------------------------------------- ------------------------------- 2016/3/1 9: 01-3月 -16 09.22.33.000000 上午 01-3月 -16 09.22.33.000000 上午 +08:00 01-3月 -16 09.22.33.000000 上午
ALTER SESSION SET TIME_ZONE = '+10:00'; SELECT * FROM timestamp_test; DT TP TP_TZ TP_L_TZ ----------- ------------------------------- ------------------------------------- ------------------------------- 2016/3/1 9: 01-3月 -16 09.22.33.000000 上午 01-3月 -16 09.22.33.000000 上午 +08:00 01-3月 -16 11.22.33.000000 上午
| 場景 | 建議型別 | 理由 |
|---|---|---|
| 單一時區應用、不需跨時區顯示 | TIMESTAMP | 簡單高效,避免時區轉換開銷 |
| 需保留原始時區資訊(如全球事件日誌) | TIMESTAMP WITH TIME ZONE | 完整保留事件發生時的本地時間上下文 |
| 多時區用戶、需自動顯示本地時間 | TIMESTAMP WITH LOCAL TIME ZONE | 透明支援用戶端時區自適應顯示 |
TIMESTAMP WITH LOCAL TIME ZONE 不儲存時區資訊,無法從資料反推原始時區DBTIMEZONE) 建立後難以變更,規劃時務必審慎WITH LOCAL TIME ZONE 讀寫,舊版驅動需升級依據業務時區需求選擇正確的 TIMESTAMP 子類型,是全球化應用資料層設計的關鍵決策。