2017-10-02 4 views
1

저는이 쿼리가 왜 작동하지 않는지 이해하기 위해 애를 썼습니다. 이 소유자의 모든 파티션 이름은 'R_DATE_20170831'형식의 값을가집니다. 그러나 아래 쿼리는 항상 오류를 반환합니다. ORA-01841 (전체) 연도는 -4713에서 +9999 사이 여야하며 0이 아니어야합니다. 각 날짜 부분을 개별적으로 표시 할 때 모두 해당 범위 내에 있습니다. 내 NLS_DATE_FORMAT은 'DD-MON-RR'값을 표시합니다. 이 날짜 비교 오류의 원인은 무엇입니까?

SELECT COUNT(*) 
FROM dba_tab_partitions 
WHERE table_owner = 'myId' AND 
     TO_DATE(SUBSTR(partition_name,INSTR(partition_name,'_',1,2) + 1),'YYYYMMDD') < TRUNC(SYSDATE) - 10; 

나는 또한 SYSDATE-10의 주위에 적절한 마스크와 TO_DATE 퍼팅 시도했지만 여전히 오류가 발생했습니다. 어떤 통찰력? 고맙습니다!

+0

당신이 지금 올바른 가지고 구문. 네가 잘못 된 행을 잡지 못하는 것 같아. "각 날짜 부분을 개별적으로 어떻게 표시합니까"? 예를 들어, date로 변환하는 SUBSTR 부분이 항상 8 자인지 여부를 먼저 테스트 했습니까? ** 또한 ** : 정확한 오라클 버전 (Subversion 포함 - 12.1.0.2.0 등)을 기재하십시오. Oracle 12.2에는 새로운 검증 기능 VALIDATE_CONVERSION이 있습니다.이 기능은 이러한 검증 작업을 신속하게 수행 할 수 있습니다. – mathguy

답변

2

WHERE식이 반드시 순서대로 평가되지 않는다는 사실 때문에 SQL Server에서 비슷한 것을 보았습니다. 즉, 다른 파티션이 날짜 산술 논리를 통과하여 오류가 발생하고 있음을 의미합니다.

CASE은 평가 순서를 보장합니다. 이게 효과가 있니?

SELECT COUNT(*) 
FROM dba_tab_partitions 
WHERE table_owner = 'myId' AND 
     (CASE WHEN table_owner = 'myId' 
      THEN TO_DATE(SUBSTR(partition_name, INSTR(partition_name, '_', 1, 2) + 1), 'YYYYMMDD') 
     END) < TRUNC(SYSDATE) - 10; 

또는이 버전 :

SELECT COUNT(*) 
FROM dba_tab_partitions 
WHERE table_owner = 'myId' AND 
     (CASE WHEN regexp_like(partition_name, '[^_]*_[^_*]_[0-9]{8}$' 
      THEN TO_DATE(SUBSTR(partition_name, INSTR(partition_name, '_', 1, 2) + 1), 'YYYYMMDD') 
     END) < TRUNC(SYSDATE) - 10; 
+0

'table_owner = 'myId'' 부분을 인라인보기로 옮겼지만이 CASE 솔루션을 좋아합니다. – kfinity

+0

그건 실제로 일반적인 문제입니다. 옵티 마이저 (Oracle 또는 기타)가 술어를 푸는 것이 더 빠른 실행을 가져올 것이라고 생각할 때마다 이러한 종류의 동작을 볼 수 있습니다. 영업 담당자는 그가 각 날짜 부분을 개별적으로 점검했을 때 모든 것이 정상이라고 말했습니다. 어쨌든, 좋은 대답! – mathguy

+0

"각 부분을 따로 표시하려면"where 절의 두 가지 주요 부분을 가져 와서 select 절로 이동하여 표시했습니다. 시각적으로 선택된 값은 모두 DD-MMM-YY 형식의 9 문자였으며 첫 번째 값의 상당수는 두 번째 값 (예 : R_DATE_20170831 및 23-SEP-17의 partition_name에서 가져온 31-AUG-17)이었습니다. sysdate-10에서 가져옴). 위의 첫 번째 CASE 쿼리를 실행하면 오류없이 실행되지만 결과는 0입니다. 다시 한 번 그 결과를 많이 얻어야하는 것처럼 보입니다. – scotto