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

ORA-01861「字面值與格式字串不匹配」徹底解決:NLS_DATE_FORMAT 三層優先級與最佳實踐

     編輯:Oracle 資料庫基礎

錯誤現場

INSERT INTO t(dt_col) VALUES ('28-JAN-2023');
-- ORA-01861: literal does not match format string

重裝 OS/Oracle Client 後發生,原本正常的插入失效。

核心機制:Session 日期格式三層優先級

**Session 級設定會覆蓋所有上層設定。**

日期存儲與顯示本質

  • 資料庫內部儲存:**固定 7 位元組**(世紀、年、月、日、時、分、秒),**無格式、無時區**。
  • 顯示格式**完全由 Session NLS 決定**,與儲存無關。
  • 插入時若不轉型,**字串必須完全符合當前 Session NLS_DATE_FORMAT** 才能隱式轉型成功。

標準解法:顯式 TO_DATE

-- 無論環境如何,永遠安全
INSERT INTO t(dt_col) VALUES (TO_DATE('2023-01-28 15:30:00','YYYY-MM-DD HH24:MI:SS'));
INSERT INTO t(dt_col) VALUES (TO_DATE('28-JAN-2023','DD-MON-YYYY'));

Client 端永久修正(Windows)

  1. 開啟 `regedit`。
  2. 定位 `HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\HOME0`(或 HOME1...)。
  3. 新增字串值 `NLS_DATE_FORMAT` = `YYYY-MM-DD HH24:MI:SS`。
  4. 重啟 SQL*Plus / PL/SQL Developer / 應用程式。

Linux/Unix 環境變數法

# ~/.bash_profile 或 /etc/profile
export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
export NLS_LANG='AMERICAN_AMERICA.ZHS16GBK'  # 字符集一致性
# 重新登入生效

應用程式層面最佳實踐

  1. **所有日期字串轉型一律使用 `TO_DATE`/`TO_TIMESTAMP` 顯式指定格式**,杜絕隱式轉型。
  2. 連線池初始化時執行 `ALTER SESSION SET NLS_DATE_FORMAT=...` 統一格式。
  3. 避免在 SQL 腳本、排程作業中依賴環境預設格式。

快速診斷當前格式

SELECT SYSDATE FROM dual;
-- 輸出即為當前 NLS_DATE_FORMAT 顯示範例
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
層級範圍設定方式優先級
1. Session 級當前連線`ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'`最高
2. 用戶/Client 環境該用戶所有連線Windows 註冊表 `HKLM\SOFTWARE\Oracle\HOME0\NLS_DATE_FORMAT`
Linux/Unix 環境變數 `export NLS_DATE_FORMAT=...`
次之
3. 資料庫/Instance 級全庫預設`NLS_DATE_FORMAT` 參數(不建議動態修改)最低