2012-09-26 41 views
6

我有一個具有以下字段的表:甲骨文:不是一個有效的一個月

報告(表名) Rep_Date(日期) Rep_Time(日期)

的Rep_Time字段值類似'01/01/1753 07:30:00'即時間部分是相關的。我寫了下面的查詢:

select Reports.pid, MaxDate from Reports 
INNER JOIN (
    select pid, max(TO_DATE(TO_CHAR(REP_DATE, 'DD/MM/YYYY') 
     || TO_CHAR(REP_TIME, 'HH24:MI:SS'), 'DD/MM/YYYY HH24:MI:SS')) As MaxDate 
    from reports 
    group by pid 
) ReportMaxDate 
on Reports.PID = ReportMaxDate.PID 
AND To_Date(To_Char(MaxDate, 'DD/MM/YYYY')) = REP_DATE 
WHERE REPORTS.PID=61 

查詢的派生表的一部分運行,但是當我運行整個查詢,我得到一個錯誤:「不是有效的月份」。爲什麼是這樣?

爲了幫助調試,如果我運行以下查詢:

select rep_date, rep_time from reports where pid=61 and rownum=1 

我得到:

Rep_Date = 01/04/2009 
Rep_Time = 01/01/1753 13:00:00 

UPDATE 15:58 我現在可以執行以下查詢:

select Reports.pid, MaxDate from Reports 
INNER JOIN (
    select pid, max(TO_DATE(TO_CHAR(REP_DATE, 'DD/MM/YYYY') 
     || TO_CHAR(REP_TIME, 'HH24:MI:SS'), 'DD/MM/YYYY HH24:MI:SS')) As MaxDate 
    from reports group by pid 
) ReportMaxDate 
on Reports.PID = ReportMaxDate.PID 
AND to_date(to_char(maxdate,'MM/DD/YYYY'),'MM/DD/YYYY') = REP_DATE 
WHERE REPORTS.PID=61 

不過,我需要向WHERE子句添加一條語句,比較MaxDate的時間部分與rep_time:to_date(to_char(maxdate,'MM/DD/YYYY'),'MM/DD/YYYY') = REP_DATE不起作用。

回答

21

1.

To_Date(To_Char(MaxDate, 'DD/MM/YYYY')) = REP_DATE 

導致問題。當你使用沒有時間格式的to_date時,oracle會使用當前會話的NLS格式進行轉換,在你的情況下可能不是「DD/MM/YYYY」。如果你想忽略時間選中此...

SQL> select sysdate from dual; 

SYSDATE 
--------- 
26-SEP-12 

Which means my session's setting is DD-Mon-YY 

SQL> select to_char(sysdate,'MM/DD/YYYY') from dual; 

TO_CHAR(SY 
---------- 
09/26/2012 


SQL> select to_date(to_char(sysdate,'MM/DD/YYYY')) from dual; 
select to_date(to_char(sysdate,'MM/DD/YYYY')) from dual 
       * 
ERROR at line 1: 
ORA-01843: not a valid month 

SQL> select to_date(to_char(sysdate,'MM/DD/YYYY'),'MM/DD/YYYY') from dual; 

TO_DATE(T 
--------- 
26-SEP-12 

2.

更重要的是,你爲什麼要轉換爲char,然後到今天爲止,而不是直接比較

MaxDate = REP_DATE 

組件在MaxDate比較之前,應該使用..

trunc(MaxDate) = rep_date 

改爲。

==更新:基於更新的問題。

Rep_Date = 01/04/2009 Rep_Time = 01/01/1753 13:00:00 

我覺得問題更復雜。如果rep_time僅用於時間,那麼您不能將它作爲日期存儲在數據庫中。它必須是時間間隔的字符串或日期,或數字的秒數(感謝Alex,請參閱this)。如果可能的話,我會建議使用一個包含日期和時間的列rep_date,並將其直接與最大日期列進行比較。

如果它是一個正在運行的系統,並且您無法控制repdate,那麼可以試試這個。

trunc(rep_date) = trunc(maxdate) and 
to_char(rep_date,'HH24:MI:SS') = to_char(maxdate,'HH24:MI:SS') 

無論哪種方式,時間被保存不當(如可以從1753年告訴),並有可能是向前發展等問題。

+0

在回答你的問題MaxDate是一個DateTime和REP_DATE是一個日期。 Trunc(MaxDate)= rep_date做什麼? – w0051977

+0

trunc(date)將刪除時間組件(實際上,它使得時間組件爲零,對於諸如REP_DATE的日期列就是這種情況。在Oracle中沒有像日期那樣的東西。) –

+0

+1,謝謝作品。你能解釋一下如何在我接受之前獲取日期時間的時間部分嗎? to_date(to_char(maxdate,'HH24:MI:SS'),'HH24:MI:SS')似乎不起作用。 – w0051977

2

要知道激活日期格式,請使用sysdate插入記錄。由您可以找到actuel日期格式。例如

insert into emp values(7936,'Mac','clerk',7782,sysdate,1300,300,10); 

現在,選擇插入的記錄。

select ename,hiredate from emp where ename='Mac'; 

結果是

ENAME HIREDATE 
Mac  06-JAN-13 

瞧,現在你的actuel日期格式中找到。