2013-10-16 3 views
2

나는 테이블날짜 형식 : 잘못된 월

데이터 형식 아래

2003년 10월 29일

2003년 10월 21일 오전 7시 26분 0초을하고 난 날짜를 비교하려면 '07 -14-2013 '과 '09 -15-2013'사이에 있으며

to_char (to_date (a.TEXT_VALUE, 'DD-MM-YYYY HH : MI : SS AM')) 코드를 작성했습니다. 'dd-mm-YYYY') : '07-14-2013 00:00:00 AM '및 '09 -15-2013 00:00:00 AM'

이것은 작동하지 않습니다. 나는이 두 날짜 사이에 날짜를 잡으려면 무엇을 제안해야합니까?

고마워요.

+0

텍스트 필드의 값은 얼마나 다양합니까? 일정한 날짜, 12 시간 형식의 시간 (AM/PM 포함) 및 24 시간 형식의 날짜가 혼합되어 있습니까? 모든 날짜가 동일한 MM/DD/YYYY 형식으로되어 있는지 확인하십시오. 이것이 날짜가 절대로'varchar2' 열에 저장되어서는 안되며, 항상'date' 열에 저장되어야하는 이유입니다. –

+0

나는이 형식들만 가지고 있습니다. – user1465978

+1

당신은이 형식들만 가지고 있다고 가정합니다. 응용 프로그램은 varchar 필드에 무엇이든 붙을 수 있습니다. – tbone

답변

4

날짜와 달이 바뀌 었습니다.

to_char(to_date(a.TEXT_VALUE, 'MM-DD-YYYY HH:MI:SS AM'),'mm-dd-YYYY') between '07-14-2013 00:00:00 AM' and '09-15-2013 00:00:00 AM' 
+0

지금은 시간이 1과 12 사이 여야합니다 내가 HH24를 유지하는 경우가 HH24는 자오선 표시 – user1465978

+0

의 사용을 배제라고 말한다 @ user1465978, ALTER SESSION SET NLS_DATE_FORMAT = 'MM-DD-YYYY HH : MI : SS AM'; – ajmalmhd04

+0

그래서 '07 -14-2013 '과 '09 사이에 to_char (to_date (a.TEXT_VALUE,'MM-DD-YYYY HH24 : MI : SS AM '),'mm-dd-YYYY ' -15-2013 ' 정확히 말해주세요 – user1465978

0

당신은 MM/DD/YYYY HH24:MI:SS와 형식 MM/DD/YYYYMM/DD/YYYY HH:MI:SS AM, 그리고 아무도과 날짜가 있다고했습니다 미국인 (그리고 아마도 다른 나라도)은 MM-DD-YYYY의 표기법을 사용합니다. 오류 메시지가 표시되면 실수로 표시됩니다. '시간은 1과 12 사이 여야합니다'는 24 시간 형식의 시간이있는 행이 하나 이상 있음을 의미합니다. 또는, 잠재적으로, 인식 할 수없는 시간이 아닌 무언가로.

올바른 데이터 유형 대신 varchar2으로 프리 텍스트 필드에 구조화 된 데이터 (이 경우 date)를 저장할 때의 문제는 거기에 오래된 쓰레기를 가져올 수 있다는 것입니다. 응용 프로그램은 입력 된대로 데이터의 유효성을 검사합니다. 현재보고있는 내용을 기반으로하지 않는 것 같습니다. 음, 중요한 문제 중 하나는 성능에 영향을 미치는 것을 포함하는 다른 것들이 있습니다.

데이터를 구제하려고하는 유일한 방법은 여러 번 변환을 시도하는 함수를 작성하는 것입니다.이 함수는 무언가가 유효하거나 옵션이 없을 때만 반환합니다. 이 아마도 같은 뭔가 :

create or replace function clean_date(text_value varchar2) return date is 
begin 
    begin 
    return to_date(text_value, 'MM/DD/YYYY HH24:MI:SS'); 
    exception 
    when others then 
     null; 
    end; 

    begin 
    return to_date(text_value, 'MM/DD/YYYY HH:MI:SS AM'); 
    exception 
    when others then 
     null; 
    end; 

    return null; 
end clean_date; 
/

이 두 포맷을 시도하고 있지만 데이터가 필요 당신이 더 추가 할 수 있습니다 - null 다시 얻을 수있는 행은 시도 형식 중 하나로 변환 할 수 없습니다. 잘못된 일치 가능성을 피하기 위해 테스트 순서에 약간주의해야합니다. 각 begin/exception/end 하위 블록은 하나의 형식을 테스트하고 있습니다. catch other 이상적인 것은 아니지만, 대안은 고통스럽고 오류가 발생하기 쉬운 모든 날짜 형식 예외를 선언하는 것입니다. 예외가 없으면 해당 날짜 값이 반환됩니다. 예외가 있으면 아무 것도하지 않고 다음 블록으로 이동하여 다음 형식을 시도합니다.

영어로 된 날짜가 DD/MM/YYYY 인 경우 실제로 예상치 못한 일이 발생해도 항상 도움이되지 않습니다. 예를 들어 요일과 월 모두 13 미만인 경우 불가능합니다. 어떤 것이지 말하십시오.당신이 원하는 경우

where trunc(clean_date(a.text_value)) 
    between date '2013-07-14' and date '2013-09-15' 

당신은 문자열로 다시 변환 할 수 있습니다 만, 여전히 비교를위한 올바른 데이터 형식을 사용합니다 :

어쨌든

이와 필터가 될 수

where to_char(clean_date(a.text_value), 'YYYY-MM-DD') 
    between '2013-07-14' and '2013-09-15' 
1

다른 사람들도 말했듯이, 당신은 정말로 그 varchar 필드에 무엇이 있는지 모릅니다. 그리고 날짜는 날짜로 저장되어야합니다 (그래서 당신은 날짜를 가지고 멋진 것들을 모두 할 수 있습니다, 그들을 비교하고, 빼고, 날짜 범위를 가져올 수 있습니다.) ..).

잘못된 날짜가있는 레코드가 하나라도있는 경우 to_date가 중단됩니다. 그러나, 당신은 당신은 단지 날짜 범위 내에 기록을 잡고 싶은 말, 당신은 SUBSTR을 사용하여 날짜의 시간 부분을 무시 (여전히 일 유효) 희망 수 있습니다

with date_strings as 
(
    select 1 as id, '01/31/2013' as dte_str from dual 
    union 
    select 2 as id, '02/01/2013 13:55:01' as dte_str from dual 
    union 
    select 3 as id, '02/28/2013 10:30:01 AM' as dte_str from dual 
    union 
    select 4 as id, '03/01/2013 11:15:01 AM' as dte_str from dual 
) 
select 
id, dte_str, to_date(substr(dte_str, 1, 10), 'MM/DD/YYYY') as dte 
from date_strings 
where to_date(substr(dte_str, 1, 10), 'MM/DD/YYYY') between 
    to_date('02/01/2013', 'MM/DD/YYYY') and to_date('03/01/2013', 'MM/DD/YYYY')-1; 

이 예는이 행을 잡고 2013 년 2 월 어딘가에있는 날짜 (또는 문자열의 MM/DD/YYYY 부분이 잘못된 행을 1 행으로 갖고있는 경우 오류가 발생합니다 (예 : 02/29/2013). 그러나 최소한 시간 형식의 변형은 무시할 수 있습니다.