ORACLE中DATE自動轉化為TIMESTAMP
阿新 • • 發佈:2019-01-23
今天在寫SELECT語句的時候發現始終差不出來等於某個日期的資料,後來才發現是ORACLE內部發生的轉化。
3、像碰到這樣的問題,我首先想到的是檢視執行計劃
"T_DATE"=TO_DATE(' 2014-11-28 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
廢話不多說,直接看示例。
1、構建資料
由上面可以看出建立了一個表T,其中有一個型別為DATE的T_DATE欄位show parameter nls_date_format NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ nls_date_format string YYYY-MM-DD DROP TABLE t PURGE; CREATE TABLE t AS SELECT (SYSDATE + LEVEL) AS t_date FROM dual CONNECT BY LEVEL < 10; CREATE INDEX idx_t ON t(t_date); SELECT * FROM t; T_DATE ---------- 2014-11-28 2014-11-29 2014-11-30 2014-12-01 2014-12-02 2014-12-03 2014-12-04 2014-12-05 2014-12-06 SELECT table_name, column_name, data_type FROM USER_TAB_COLUMNS WHERE table_name = 'T'; TABLE_NAME COLUMN_NAME DATA_TYPE ------------------------------ ------------------------------ -------------------- T T_DATE DATE
2、困擾怎麼沒有資料出來
SELECT * FROM t WHERE t_date='2014-11-28';
no rows selected
難道是沒有將2014-11-28轉換成DATE型別的原因?SELECT * FROM t WHERE t_date=TO_DATE('2014-11-28', 'yyyy-mm-dd');
no rows selected
還是沒有,真奇怪!3、像碰到這樣的問題,我首先想到的是檢視執行計劃
以上兩種查詢方法建議使用第二種,它使用了顯示型別轉化,更具有可讀性,等讓人明白。
通過上面的執行計劃,可以看到ORACLE自動發生了DATE -> TIMESTAMP的轉化:SET AUTOTRACE ON EXPLAIN SELECT * FROM t WHERE t_date=TO_DATE('2014-11-28', 'yyyy-mm-dd'); no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 2296882198 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 9 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| IDX_T | 1 | 9 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("T_DATE"=TO_DATE(' 2014-11-28 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic sampling used for this statement (level=2)
"T_DATE"=TO_DATE(' 2014-11-28 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
4、所以我們要查詢出相關時間只能是另尋他法了。
由上看到資料終於查出來了SELECT * FROM t WHERE t_date >= TO_DATE('2014-11-28', 'yyyy-mm-dd') AND t_date < TO_DATE('2014-11-29', 'yyyy-mm-dd'); T_DATE ---------- 2014-11-28 Execution Plan ---------------------------------------------------------- Plan hash value: 2296882198 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 9 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| IDX_T | 1 | 9 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("T_DATE">=TO_DATE(' 2014-11-28 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "T_DATE"<TO_DATE(' 2014-11-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) Note ----- - dynamic sampling used for this statement (level=2)