제가 요즘 좀 이상한 SQL들을 시도하고 있는데요...
좀 이상한 오류가 나서 말씀드립니다.
먼저 다음의 SQL을 봐주십시오.
with base_data as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
from dual
)
, base_data2 as
(
select
a.id
, ( select count(*) from table(a.vs)) val
,(select collect (column_value) from table(a.vs)) vs
from base_data a
)
select
a.id
,a.val
,(select count(*) from table(a.vs) ) cnt
from base_data2 a
/
이 SQL을 실행한 결과는
ID VAL CNT
A 1 1
입니다.
여기서 알 수 있는 것은 스칼라 서브쿼리로 a.vs가 collection type 인 경우 다음과 같은 SQL이 가능하다는 겁니다.
" (select collect (column_value) from table(a.vs)) "
물론 위의 SQL은 결과적으로 아래의 SQL과 동일한 의미입니다.
with base_data as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
from dual
)
, base_data2 as
(
select
a.id
, ( select count(*) from table(a.vs)) val
, a.vs
from base_data a
)
select
a.id
,a.val
,(select count(*) from table(a.vs) ) cnt
from base_data2 a
/
즉
(select collect (column_value) from table(a.vs)) 는 a.vs 와 같다는 것을 알 수 있습니다.
심지어는 다음과 같이 마구 마구 사용할 수 있습니다.
with base_data as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
from dual
)
, base_data2 as
(
select
a.id
, ( select count(*) from table(a.vs)) val
,(select collect (column_value) from table(a.vs)) vs
from base_data a
)
select
a.id
,a.val
,(select count(*) from table(a.vs) ) cnt
,(select max(column_value) from table(a.vs) ) cnt
from base_data2 a
, table(a.vs) b
, table(a.vs) c
/
그런데 아래와 같이 해당 SQL 문법을 recursive-with 에서 사용하면 에러가 납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
,(select collect (column_value) from table(a.vs)) vs
, ( select count(*) from table(a.vs)) val
, cnt + 1
from base_data a
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
오류는 ORA-00600: 내부 오류 코드, 인수: [kologsf1], [], [], [], [], [], [], [], [], [], [], []
이라고 나옵니다.
그런데
위의 SQL을 다음과 같이 바꾸면 안납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
, a.vs
, ( select count(*) from table(a.vs)) val
, cnt + 1
from base_data a
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
ID VAL
A 0
B 1
위에서 본 것처럼 a.vs 나 (select collect (column_value) from table(a.vs))는 사실상 같은 의미입니다.
그런데 위의 SQL을 약간 확장하여 다음과 같이 쓰면 동일한 오류가 납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
, a.vs
, ( select count(*) from table(a.vs)) val
, cnt + 1
from base_data a
, table(a.vs) b
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
ORA-00600: 내부 오류 코드, 인수: [kologsf1], [], [], [], [], [], [], [], [], [], [], []
그런데 " table(a.vs) b " 는 적법한 사용법입니다.
왜냐면 위의 SQL을 다음과 같은 방법으로 쓰면 오류가 안납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
,(select collect (level) from dual connect by level < 2) vs
, 1 val
, cnt + 1
from base_data a
, table(a.vs) b
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
ID VAL
A 0
B 1
마치 table(a.vs)를 두번 이상 쓰면 오류가 나는 것 같습니다.
테스트를 위해 다음과 같은 SQL을 쓰면 오류가 납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
,(select collect (level) from dual connect by level < 2) vs
, 1 val
, cnt + 1
from base_data a
, table(a.vs) b
, table(a.vs) c
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
ORA-00600: 내부 오류 코드, 인수: [kologsf1], [], [], [], [], [], [], [], [], [], [], []
그런데 위에서 table(a.vs) 형태는 아니지만 a.vs 와 table(a.vs) 를 같이 쓴 경우는 오류가 없었습니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
, a.vs
, ( select count(*) from table(a.vs)) val
, cnt + 1
from base_data a
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
그런데
a.vs와 table(a.vs)를 같이 사용하면서 table(a.vs)를 from절에 놓으면 다시 오류가 납니다.
with base_data ( id,vs,val,cnt ) as
(
select
'A' id
,(select collect (level) from dual connect by level < 2) vs
,0
,1
from dual
union all
select
'B'
, a.vs
, 1 val
, cnt + 1
from base_data a
, table(a.vs ) b
where cnt < 2
)
select
a.id
,a.val
from base_data a
/
ORA-00600: 내부 오류 코드, 인수: [kologsf1], [], [], [], [], [], [], [], [], [], [], []
왜 이런 문제가 있을까요?
혹시 아시는 분이 계시면 답글 부탁드립니다.
만약 recursive-with에서 다중 행을 재귀시킬 수 있다면 훨씬 다양한 SQL이 가능해집니다.
그래서 이 문제를 해결하고 싶은데...
아시는 분 부탁드립니다.
|