程式在開發機正常,部署至測試機後,涉及日期字串轉換的 SQL 陳述式拋出:
Error 242, Severity 16, State 3: The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
事件探查器捕捉到連線時的語言設定為:
set language romana
set dateformat ymd
而開發機為 set language 簡體中文 (或 us_english)。語言不同導致預設日期格式解析邏輯不同 (如 dd/MM/yyyy vs MM/dd/yyyy),造成相同字串在不同環境解析結果不一甚至失敗。
DATEFORMAT (mdy/dmy/ymd 等),影響隱含字串轉日期的解析順序。所有日期字串一律使用 ISO 8601 格式:YYYYMMDD 或 YYYY-MM-DDTHH:MM:SS,此格式不受語言/日期格式設定影響。
-- 安全範例
WHERE OrderDate >= '20240115' -- 無歧義
WHERE OrderDate >= '2024-01-15T00:00:00' -- 標準 ISO
-- 避免
WHERE OrderDate >= '01/15/2024' -- 視語言解析為 1月15日 或 15月1日
ADO 連線物件 Properties("Current Language") = "Simplified Chinese" (或 us_english)。確保所有連線 (含動態建立) 皆設定。
Dim conn As New ADODB.Connection
conn.Properties("Current Language") = "Simplified Chinese"
conn.Open "..."
企業管理員 → 安全性 → 登入 → 右鍵屬性 → 「預設語言」設為統一值 (建議 us_english 或 Simplified Chinese)。
-- 連線建立後立即執行
SET LANGUAGE 'us_english'; -- 或 'Simplified Chinese'
-- 亦可搭配
SET DATEFORMAT YMD; -- 強制年月日順序
SELECT @@LANGUAGE AS CurrentLanguage,
DATENAME(month, '2024-01-15') AS MonthName,
DATENAME(weekday, '2024-01-15') AS WeekdayName;
-- 檢查輸出是否符合預期
| 語言 | 預設 DATEFORMAT | 日期範例 '01/02/03' 解析為 |
|---|---|---|
| us_english | mdy | 2003-01-02 |
| British | dmy | 2003-02-01 |
| Simplified Chinese | ymd | 2001-02-03 |
| Japanese | ymd | 2001-02-03 |
| German | dmy | 2003-02-01 |
| French | dmy | 2003-02-01 |
跨環境日期轉換錯誤 90% 以上源於語言/日期格式不一致。強制使用 ISO 8601 日期字串 是唯一徹底解法;輔以統一連線語言設定,可雙重保障。切勿依賴隱含轉換,將日期格式納入程式碼規範強制檢查。