이 exemple이 같은 일의 목록을 작성하기 위해 오라클 계층 하위 쿼리를 사용하는 우리의 개발자와의 여기에 많은 이상한 물건 : 나를 위해오라클 내부 날짜 변환 : ORA-00932 및
WITH mydays AS (
SELECT CAST(TO_DATE('20161201', 'YYYYMMDD') + ROWNUM AS DATE) AS d
FROM DUAL CONNECT BY TO_DATE('20161201', 'YYYYMMDD') + ROWNUM <= to_date('20161215', 'YYYYMMDD')
)
는 모습 CAST ... DATE을 DATE로 변환하기 때문에 DATE는 쓸모가 없어야합니다. 실제로는 그렇지 않습니다. 내가 만들고이 같은 테이블을 채우는 (나는 내 데모에 가입해야합니다 ...) 경우 : CAST없이,
create table t(d date, i number);
insert into t(d, i) values (to_date('20161204', 'YYYYMMDD'), 1);
commit;
을하고 그런 식으로 가입하여 쿼리를 시도, 나는이 계획을 설명 다음 얻을 :
WITH mydays AS (
SELECT TO_DATE('20161201', 'YYYYMMDD') + ROWNUM AS d
FROM DUAL CONNECT BY TO_DATE('20161215', 'YYYYMMDD') + ROWNUM <= to_date('20161201', 'YYYYMMDD')
)
select mydays.d from mydays join t on t.d = mydays.d;
. 캐스트와 함께
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 15 | 6 (17)| 00:00:01 |
|* 1 | HASH JOIN | | 1 | 15 | 6 (17)| 00:00:01 |
| 2 | VIEW | | 1 | 6 | 2 (0)| 00:00:01 |
| 3 | COUNT | | | | | |
|* 4 | CONNECT BY WITHOUT FILTERING| | | | | |
| 5 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | T | 1 | 9 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T"."D"=INTERNAL_FUNCTION("MYDAYS"."D"))
4 - filter(TO_DATE(' 2016-12-15 00:00:00', 'syyyy-mm-dd
hh24:mi:ss')+ROWNUM<=TO_DATE(' 2016-12-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
의 INTERNAL_FUNCTION는() 사라 :
4 - filter(TO_DATE(' 2016-12-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss')+ROWNUM<=TO_DATE(' 2016-12-15 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
내가 조금 인터넷 검색 및 변환이 ID (12)와 오라클 내부적으로 처리, 두 개의 내부 날짜 형식 사이 것을 발견 13, DUMP()에 대한 호출을 찾을 수 있습니다.
Typ=13 Len=8: 7,224,12,4,0,0,0,0
캐스트와 함께 : 캐스트없이
Typ=12 Len=7: 120,116,12,4,1,1,1
우리가하지 않고보다 CAST 덜 변환을해야한다고 설명한다 (!).
하지만 바인딩 변수를 넣으면 악화됩니다. 내가 얻고 싶은 경우,이 SQL의 계획을 설명 : ORA-00932 : 일관성없는 데이터 유형 : 예정일이 번호를 가지고
WITH mydays AS (
SELECT TO_DATE(:beginning, 'YYYYMMDD') + ROWNUM AS d
FROM DUAL CONNECT BY TO_DATE(:end, 'YYYYMMDD') + ROWNUM <= to_date(:beginning, 'YYYYMMDD')
)
select mydays.d from mydays join t on t.d = mydays.d
나는 오류가 발생합니다. CAST 마법을 추가하면 오류가 수정됩니다. 나는 계획을 생성 할 때 모든 바인드 변수가 VARCHAR2로 간주된다는 것을 알고 있습니다. 하지만 TO_DATE()에서는 DATE와 만 작업해야합니다. 맞습니까? 이 번호의 출처는 어디입니까?
내 뇌가 그 이상한 것들로 매우 지저분 해지기 시작하면 설명해 줄 수 있으면 고마워.
CAST – Leo
없이 오류없이 성공적으로 쿼리가 실행되었습니다. 사실 서브 쿼리의 종류를 사용하여보다 복잡한 쿼리를 작성하고 있으며 개발 중 100 %의 시간 동안 작동합니다. 생산의 시대. 오라클은이 쿼리에 대해 많은 설명 계획을 사용하고 있으며, 문제를 유발하는 계획은 하나 뿐이며 현재 어느 쿼리를 찾을 수 없습니다. –
사용중인 Oracle 버전은 무엇입니까? 관찰 된 동작 ("외부"날짜 형식으로 문제가 발생하는 경우)은 특정 버전에 따라 매우 다를 수 있습니다. 'select * from v $ version'가 도움이 될 수 있습니다. – mathguy