Oracle: 올바른 월이 아님
다음 필드가 있는 테이블이 있습니다.
리포트(테이블명) 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
쿼리에서 파생된 테이블 부분이 실행되지만 전체 쿼리를 실행하면 "not avalid month"라는 오류가 나타납니다.왜 이러한가?
디버깅을 돕기 위해 다음 쿼리를 실행하면 다음과 같습니다.
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
업데이트 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
작동하지 않습니다.
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.
더 중요한 것은, 왜 직접적으로 비교하는 대신에 차로 전환하고 또 데이트로 전환하느냐는 것입니다.
MaxDate = REP_DATE
비교하기 전에 MaxDate의 시간 구성 요소를 무시하려면 다음을 사용해야 합니다.
trunc(MaxDate ) = rep_date
대신.
==Update : 업데이트된 질문을 기반으로 합니다.
Rep_Date = 01/04/2009 Rep_Time = 01/01/1753 13:00:00
문제는 더 복잡하다고 생각합니다. rep_time을 시간으로만 사용하고자 하는 경우 데이터베이스에 날짜로 저장할 수 없습니다.문자열 또는 날짜 대 시간 간격 또는 숫자로 초 단위여야 합니다(알렉스 덕분에 참조). 가능하다면 날짜와 시간을 모두 포함하는 하나의 열 rep_date를 사용하여 최대 날짜 열과 직접 비교하는 것을 제안합니다.
실행 중인 시스템인데 재데이트에 대한 제어권이 없다면 이를 시도해 볼 수 있습니다.
trunc(rep_date) = trunc(maxdate) and
to_char(rep_date,'HH24:MI:SS') = to_char(maxdate,'HH24:MI:SS')
어느 쪽이든 시간이 잘못 저장되고 있으며(1753년에서 알 수 있듯이) 앞으로 다른 문제가 발생할 수 있습니다.
실제 날짜 형식을 보려면 sysdate를 사용하여 레코드를 삽입합니다.그렇게 하면 실제 날짜 형식을 찾을 수 있습니다.예를들면
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
voila, 당신의 실제 날짜 형식이 발견되었습니다.
ALTER SESSION 명령을 사용하여 세션에 대한 이 데이터베이스 파라미터의 값을 변경하고 원하는 대로 사용할 수도 있습니다.
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YYYY';
SELECT TO_DATE('05-12-2015') FROM dual;
05/12/2015
'' 안의 형식을 원하는 대로 사용자 지정할 수 있습니다.
table_name에서 TO_CHAR(column_name, 'MONTH-DAY-y') 선택;
언급URL : https://stackoverflow.com/questions/12603975/oracle-not-a-valid-month
'programing' 카테고리의 다른 글
CSS를 통해 순서 목록의 두 번째 줄에 대한 들여쓰기를 유지하는 방법은 무엇입니까? (0) | 2023.09.20 |
---|---|
인쇄방법인쇄방법XDocument 사용XDocument 사용 (0) | 2023.09.20 |
자리 표시자와 대체 개체를 사용하여 자바스크립트 문자열을 포맷하시겠습니까? (0) | 2023.09.20 |
K&R C 2장의 getbits() 방법 이해에 도움이 필요합니다. (0) | 2023.09.20 |
HTML IMG 태그를 이용한 종횡비 유지 방법 (0) | 2023.09.20 |