首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Oracle TO_CHAR 日期格式 HH24:MI 在 Java 中變單數字?NLS_DATE_FORMAT 與 JDBC 驅動解析差異

     編輯:程式設計綜合問答

現象

  • SQL*Plus 執行 TO_CHAR(dt, 'YYYY-MM-DD HH24:MI') → 2014-12-10 16:12 正常。
  • Java JDBC 執行相同查詢 → ResultSet.getString() 取得 2014-12-10 16 (分號丟失) 或 16? (亂碼)。
  • 改用 HH24-MI → Java 端正常顯示 16-12。

根因分析

  1. JDBC 驅動對冒號的特殊處理:舊版 ojdbc14/ojdbc5/ojdbc6 在解析 DATE/TIMESTAMP 字串時,將冒號視為參數標記或時區分隔符,導致截斷。
  2. NLS_DATE_FORMAT Session 參數影響:若 Session 設定 NLS_DATE_FORMAT 不含分秒,驅動可能按該格式重新格式化後再傳回。

解決方案

方案一:升級 JDBC 驅動(根治)

使用 ojdbc8.jar (JDK 8+) 或 ojdbc11.jar (JDK 11+),從 Oracle 官網下載,替換專案/classpath 中舊版驅動。新版驅動正確處理冒號與時區。

方案二:SQL 層面顯式轉 VARCHAR2 避開驅動解析

SELECT TO_CHAR(dt, 'YYYY-MM-DD HH24:MI') AS dt_str FROM ...

在 Java 端用 rs.getString("dt_str") 取得純字串,繞過 DATE 類型解析邏輯。

方案三:設定 Session NLS 參數(臨時)

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';

或在連線 URL 加入:jdbc:oracle:thin:@host:port:sid?oracle.net.nls_date_format=YYYY-MM-DD HH24:MI:SS

方案四:Java 端用 LocalDateTime 直接映射 (JDBC 4.2+)

LocalDateTime ldt = rs.getObject("dt_col", LocalDateTime.class);
String formatted = ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

需驅動支援 getObject(int, Class) 且資料庫欄位為 TIMESTAMP。

最佳實踐建議

  • **資料庫儲存用 TIMESTAMP WITH TIME ZONE**,應用層統一用 Instant/ZonedDateTime 處理時區。
  • **查詢投影明確列出欄位別名**,避免 SELECT * 導致驅動隱式轉換。
  • **專案鎖定 ojdbc8/11 版本**,納入依賴管理,禁止相容模式載入舊驅動。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved