在 Kettle (Pentaho Data Integration) ETL 作業中,日期參數傳遞至 SQL 查詢作為過濾條件時,若參數格式與數據庫列格式不一致,會導致邏輯錯誤(如字符串比較而非日期比較)。本文剖析典型錯誤案例、根因及標準化修正方案。
SQL 過濾條件:
WHERE a.first_send_notice_date >= date_format('${FIRSTDAYOFLASTMONTH}', '%Y-%m-%d')
Kettle 日期參數實際傳遞值:'2015/05/01 00:00:00'(含時間、斜杠分隔)
數據庫列 first_send_notice_date 類型:DATETIME,存儲格式 '2015-05-01 00:00:00'(連字符分隔)。
mysql> select '2015/05/01 00:00:00' > '2015-05-02 00:00:00';
+------------------------------------------------------+
| '2015/05/01 00:00:00' > '2015-05-02 00:00:00' |
+------------------------------------------------------+
| 1 |
+------------------------------------------------------+
字符串按 ASCII 碼逐字符比較,'/' (47) 大於 '-' (45),導致 2015/05/01 被判定大於 2015-05-02,邏輯完全錯亂。
yyyy/MM/dd HH:mm:ss。date_format() 期望輸入格式與目標格式一致,否則隱式轉換為字符串比較。# 在「設定變量」或「修改 JavaScript 值」步驟
var formatted = dateFormat(new Date(${FIRSTDAYOFLASTMONTH}), "yyyy-MM-dd");
# 將 formatted 存入新變量供 SQL 使用
WHERE a.first_send_notice_date >= STR_TO_DATE('${FIRSTDAYOFLASTMONTH}', '%Y/%m/%d %H:%i:%s')
-- 或
WHERE a.first_send_notice_date >= CAST('${FIRSTDAYOFLASTMONTH}' AS DATETIME)
2015-05-01 00:00:00(連字符)。WHERE col >= '${PARAM}',MySQL 可隱式識別標準格式。yyyy-MM-dd HH:mm:ss。STR_TO_DATE 或 CAST 顯式指定參數類型,避免隱式轉換。DATE/DATETIME/TIMESTAMP,拒絕字符串存日期。