首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 教學

跨數據庫插入當前系統時間:Oracle、DB2、SQL Server、MySQL、PostgreSQL 語法差異對照表

     編輯:Oracle 教學

跨數據庫插入當前系統時間:Oracle、DB2、SQL Server、MySQL、PostgreSQL 語法差異對照表

異構數據庫環境下,應用遷移、數據同步、ETL 腳本編寫時,「插入當前時間」看似簡單,實則語法差異巨大。本文提供主流五大數據庫的標準函數、數據類型匹配、時區處理、批量插入性能差異對照表,並附帶 Java/JDBC 參數綁定最佳實踐。

一、 核心函數與數據類型對照表

數據庫當前日期時間函數返回類型目標列推薦類型備註
OracleSYSDATE / SYSTIMESTAMPDATE / TIMESTAMP WITH TIME ZONEDATE / TIMESTAMP(6)`SYSDATE` 精度至秒,`SYSTIMESTAMP` 精度至微秒含時區。`CURRENT_DATE` 返回會話時區時間。
DB2 (LUW)CURRENT TIMESTAMP / CURRENT TIMESTAMP(6)TIMESTAMPTIMESTAMP標準 SQL 函數。`CURRENT DATE` 僅日期。z/OS 版本語法一致。
SQL ServerGETDATE() / SYSDATETIME() / SYSUTCDATETIME()DATETIME / DATETIME2(7) / DATETIME2(7) UTCDATETIME2(7) (推薦)`GETDATE()` 精度 ~3.33ms (DATETIME);`SYSDATETIME()` 精度 100ns (DATETIME2);`GETUTCDATE()`/`SYSUTCDATETIME()` 返回 UTC。
MySQLNOW() / CURRENT_TIMESTAMP / SYSDATE()DATETIMEDATETIME(6) / TIMESTAMP(6)`NOW()` = 語句執行開始時間;`SYSDATE()` = 函數執行瞬間時間 (複製表時不同);`CURRENT_TIMESTAMP` 標準 SQL。`DATE()`/`CURDATE()` 僅日期。
PostgreSQLNOW() / CURRENT_TIMESTAMP / CLOCK_TIMESTAMP()TIMESTAMP WITH TIME ZONE (timestamptz)TIMESTAMPTZ / TIMESTAMP(6)`NOW()` = 事務開始時間 (事務內固定);`CLOCK_TIMESTAMP()` = 實時時間;`LOCALTIMESTAMP` 無時區。支援 `TIMEZONE('UTC', NOW())` 時區轉換。

二、 插入語句標準寫法示例

-- 表結構通用: CREATE TABLE test_time (id INT PRIMARY KEY, name VARCHAR(50), created_at <目標類型>);

-- Oracle
INSERT INTO test_time (id, name, created_at) VALUES (1, 'Oracle', SYSDATE);
-- 或帶微秒時區
INSERT INTO test_time (id, name, created_at) VALUES (1, 'Oracle', SYSTIMESTAMP);

-- DB2
INSERT INTO test_time (id, name, created_at) VALUES (1, 'DB2', CURRENT TIMESTAMP);

-- SQL Server
INSERT INTO test_time (id, name, created_at) VALUES (1, 'SQLServer', SYSDATETIME()); -- 高精度推薦

-- MySQL
INSERT INTO test_time (id, name, created_at) VALUES (1, 'MySQL', NOW());
-- 或指定微秒精度 (5.6.4+)
INSERT INTO test_time (id, name, created_at) VALUES (1, 'MySQL', CURRENT_TIMESTAMP(6));

-- PostgreSQL
INSERT INTO test_time (id, name, created_at) VALUES (1, 'PostgreSQL', NOW());
-- 存 UTC 時間
INSERT INTO test_time (id, name, created_at) VALUES (1, 'PostgreSQL', TIMEZONE('UTC', NOW()));

三、 時區處理:跨地域系統的關鍵

場景OracleSQL ServerMySQLPostgreSQL
獲取 UTC 時間`SYS_EXTRACT_UTC(SYSTIMESTAMP)``SYSUTCDATETIME()` / `GETUTCDATE()``UTC_TIMESTAMP()` / `CONVERT_TZ(NOW(), @@session.time_zone, '+00:00')``TIMEZONE('UTC', NOW())` / `NOW() AT TIME ZONE 'UTC'`
會話/連接時區設置`ALTER SESSION SET TIME_ZONE = '+08:00'``SET DATEFORMAT` / 連接字符串 `TimeZone=UTC``SET time_zone = '+08:00'` / `my.cnf default-time-zone``SET TIME ZONE 'UTC'` / `postgresql.conf timezone`
數據庫級默認時區安裝時指定 / `DBTIMEZONE`OS 時區`system_time_zone` / `default-time-zone``postgresql.conf timezone`
架構建議: 所有微服務、數據庫、日志系統**統一使用 UTC 存儲**,應用層按用戶時區顯示。避免夏令時切換、跨地域部署導致的時間混亂。

四、 Java/JDBC 參數綁定最佳實踐

**嚴禁**在 SQL 字符串中拼接時間函數 (如 `INSERT ... VALUES (?, SYSDATE)`),應由**應用層生成時間並綁定參數**,確保跨數據庫一致性、可測試性、避免 SQL 注入。

// Java 8+ java.time API (推薦)
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC); // 業務邏輯統一用 UTC
// 或 Instant now = Instant.now();

// PreparedStatement 綁定
String sql = "INSERT INTO test_time (id, name, created_at) VALUES (?, ?, ?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
    ps.setInt(1, 1);
    ps.setString(2, "AppInsert");
    // Oracle / PostgreSQL / MySQL / DB2 / SQL Server (JDBC 4.2+ 支援 java.time)
    ps.setObject(3, now); 
    // 老版本驅動可能需轉換
    // ps.setTimestamp(3, Timestamp.valueOf(now)); // 無時區
    // ps.setTimestamp(3, Timestamp.from(Instant.now())); // UTC
    ps.executeUpdate();
}

// 批量插入優化
ps.addBatch(); // 循環添加
ps.executeBatch();
驅動版本提醒:
  • Oracle JDBC 19c+ (ojdbc10/11) 完整支援 `java.time` (`setObject`)。
  • PostgreSQL 42.2+ 支援 `setObject(LocalDateTime)` / `OffsetDateTime`。
  • MySQL Connector/J 8.0+ 支援 `LocalDateTime`/`Instant`,需連接參數 `serverTimezone=UTC`。
  • SQL Server JDBC 7.4+ 支援 `java.time`,`setObject` 自動映射 `DATETIME2`。
  • DB2 JCC 11.5+ 支援 `java.time`。

五、 批量載入/ETL 性能差異

數據庫批量插入當前時間推薦方式性能特徵
Oracle`FORALL` + `SYSDATE` / `SYSTIMESTAMP` / `DBMS_UTIL.GET_TIME`PL/SQL 批量綁定最快;SQL*Loader 外部表 `SYSDATE` 常數列
SQL Server`BULK INSERT` / `BCP` / `INSERT ... SELECT` + `SYSDATETIME()`最小化日志模式下極快;表值參數 (TVP) 應用層批量傳遞
MySQL`LOAD DATA INFILE` + 當前時間列默認值 `DEFAULT CURRENT_TIMESTAMP`文件載入最快;避免觸發器/函數開銷
PostgreSQL`COPY` + `DEFAULT NOW()` / `INSERT ... SELECT` + `NOW()``COPY` 文本流極快;預備語句批量綁定
DB2`LOAD` / `INGEST` / `IMPORT` + `CURRENT TIMESTAMP``LOAD` 繞過日志最快

六、 避坑指南:常見錯誤與修正

  1. Oracle `ORA-01861`: `INSERT ... VALUES (TO_DATE('2024-01-01', 'YYYY-MM-DD'))` 格式不匹配 → 統一用 `TO_DATE` 顯式格式化,或綁定 `java.time.LocalDate` 參數。
  2. MySQL `TIMESTAMP` 2038 年問題: `TIMESTAMP` 範圍 1970-2038 → 使用 `DATETIME(6)` (範圍 1000-9999)。
  3. SQL Server `GETDATE()` 精度陷阱: `DATETIME` 精度 3.33ms → 關鍵業務用 `DATETIME2(7)` + `SYSDATETIME()`。
  4. PostgreSQL 事務內 `NOW()` 固定: 長事務中 `NOW()` 不變 → 需實時時間用 `CLOCK_TIMESTAMP()`。
  5. DB2 `CURRENT TIMESTAMP` 並發唯一性: 高併發可能重複 → 聯合 `GENERATE_UNIQUE()` 或序列保證唯一主鍵。

掌握異構數據庫時間函數差異、時區統一策略、JDBC 參數化綁定、批量載入優化,是構建可移植、高性能、全球化數據應用的必備技能。建議團隊建立「時間處理規範文檔」,強制 UTC 存儲、參數化綁定、顯式格式化,納入代碼審查清單。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved