2013-12-11 73 views
0
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('01/Jan/2020')),1,'Yes','No') FROM dual; 
Which returns - NO 

SELECT DECODE((SELECT COUNT(*) FROM dual where to_date(SYSDATE) BETWEEN to_date ('01/Jan/2013') AND to_date('01/Jan/2020')),1,'Yes','No') FROM dual; 
Which returns - YES 

From (01/jan/2013) to (10/Jan/2013) - returns No 
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR  ('01/Jan/2013') AND TO_CHAR('01/Jan/2020')),1,'Yes','No') FROM dual; 
to 
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR  ('01/Jan/2013') AND TO_CHAR('10/Jan/2020')),1,'Yes','No') FROM dual; 
Returns - No, 

But from 11/jan/2020 its returns Yes 
SELECT DECODE((SELECT COUNT(*) FROM dual WHERE TO_CHAR(SYSDATE) BETWEEN TO_CHAR ('01/Jan/2013') AND TO_CHAR('11/Jan/2020')),1,'Yes','No') FROM dual; 
Which returns - YES 

我不明白爲什麼oracle會像這樣返回,請讓我明白這一點。謝謝。爲什麼to_char和to_date返回不同​​的結果

+0

是的,標記爲關閉。簡而言之,將日期與其他日期進行比較,將字符串與其他字符串進行比較'01/jan/2013'是一個字符串,to_date('01/jan/2013','DD/MM/YYYY')是日期,sysdate是日期。 http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements001.htm#SQLRF0021 –

回答

1

我不確定這是相當重複的;儘管鏈接的問題涵蓋了類似的理由,但將字符串與字符串進行比較以及日期與日期的建議無疑是有效的,但您已經這樣做了,而且我不確定它是否會幫助您理解您在此處看到的內容。

關鍵是要看字符串比較時的實際字符串值是多少。我假定您的NLS_DATE_FORMAT爲DD/Mon/YYYY,因爲這是您編寫固定日期的方式,但它也可以與默認DD-MON-RR一起使用。我也忽略了來自NLS_SORT和其他設置的潛在併發症。

select to_char(sysdate), to_char('01/Jan/2013'), to_char('01/Jan/2020') from dual; 

TO_CHAR(SYSDATE)  TO_CHAR('01/JAN/2013') TO_CHAR('01/JAN/2020') 
-------------------- ---------------------- ---------------------- 
11/Dec/2013   01/Jan/2013   01/Jan/2020    

首先,固定字符串的to_char()沒有做任何事情,你一個字符串轉換爲字符串。但是想一想當你將這些值加入你的where條款時會發生什麼;

select decode(count(*), 1, 'Yes', 'No') from dual 
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('01/Jan/2020'); 

變得

select decode(count(*), 1, 'Yes', 'No') from dual 
where '11/Dec/2013' between '01/Jan/2013' and '01/Jan/2020'; 

這純粹是一個字符串比較,儘管它們仍然代表你的日期,但對於SQL引擎,它們只是字符串。第一個字符的比較失敗 - 11/Dec/2013中的第一個1與另外兩個字符串中的0進行比較,'1'不在'0''0'之間。 (簡化一下)。

當你比較反對10日,

select decode(count(*), 1, 'Yes', 'No') from dual 
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('10/Jan/2020'); 

變爲:

select decode(count(*), 1, 'Yes', 'No') from dual 
where '11/Dec/2013' between '01/Jan/2013' and '10/Jan/2020'; 

它失敗了,因爲'11'之間沒有'01''10'

在你最後一次查詢,

select decode(count(*), 1, 'Yes', 'No') from dual 
where to_char(sysdate) between to_char('01/Jan/2013') and to_char('11/Jan/2020'); 

變爲:

select decode(count(*), 1, 'Yes', 'No') from dual 
where '11/Dec/2013' between '01/Jan/2013' and '11/Jan/2020'; 

和(再次簡化位)的比較成功,因爲'11/D'是,作爲一個字符串,'01/J''11/J'之間。

使用不同的格式掩碼可以使其始終如一地工作,但唯一安全可靠的方法是將所有內容作爲日期進行比較,並在to_date()調用中明確聲明日期格式模型的固定值:

select decode(count(*), 1, 'Yes', 'No') from dual 
where sysdate between to_date('01/Jan/2013', 'DD/Mon/YYYY') 
    and to_date('01/Jan/2020', 'DD/Mon/YYYY'); 

而不要做to_date(sysdate);因爲鏈接的問題提到,對字符串進行隱式轉換,這在最好的情況下毫無意義,但如果指定了格式模型則會引入問題。如果您嘗試刪除當前日期的時間部分,則可以使用trunc(sysdate)而不是轉換爲字符串並返回。

+0

非常感謝Alex。你在這裏解釋了任何東西。再次感謝 :) – Naveen

相關問題