먼저
기존의 제 생각은 'connect by의 사이클 검증은 SQL로는
불가능하다'라는 것이었습니다.
그 이유는 '사이클 검증을 위해서는 재귀적 검증이 필요하고
오라클에서 재귀적 검증은 오로지 connect by에 의해서만 가능하고
그렇다면 결국 검증을 위한 connect by가 loop가 되어 에러가 날 것이니
connect by의 사이클 검증은 SQL로는 불가능하다' 고
생각했었습니다.
그러나 장진주님의 사이클 검증 SQL을 보고는 새로운 충격 비슷한걸
받았습니다.
그리고는 속으로 '음... 내가 고정관념을 가지고 편견을 가지고
있었구나' 생각했습니다.
그리고는 나름대로 다시 사이클 검증 SQL의 일반적 해법을 찾으려고
시도했습니다.(첨언하면 장진주님이 제시하신 사이클 검증 SQL은 특수한
경우에만 가능한 것이었습니다.이 것에대해서는 제가 손사장님이
제시하신 문제에 댓글로 올려놓은 것이 있으니 참고하십시오.)
그리고는 다음과 같은 것을 찾았는데....
제가 생각할 때 스스로 납득이 되지 않아 이렇게 글을 올립니다.
테이블은 아래의 구조 입니다. SQL> desc t_hir
이름 널? 유형
----------------------------------------- --------
----------------------------
ID NOT NULL NUMBER
NAME
VARCHAR2(100)
P_ID NUMBER
데이타는 다음과 같이 입력하고 두개의 사이클을 만들었습니다.
ID NAME P_ID
1 김흥수 9
2 오길자 4
3 백승기 1
4 김유빈 2
5 홍길동
6 전우치 5
7 전봉준 5
8 커 1
9 나 8
여기서 사이클은
김흥수->커->나->김흥수
오길자->김유빈->오길자
가 존재합니다.
다음과 같은 SQL을 날려보면
select
m,
max(p)
from(
Select
(
select
max(sys_connect_by_path(b.name,'-'))
from t_hir b
start with
b.p_id = a.ID
connect by
prior decode(a.id,b.ID,null,b.id) = b.P_ID
) p,
(
select
max(b.id)
from t_hir b
start with
b.p_id = a.ID
connect by
prior decode(a.id,b.ID,null,b.id) = b.P_ID
) m
From t_hir a
Where exists (
select
null
from t_hir b
where b.id = a.id
start with
b.p_id = a.ID
connect by
prior b.ID = b.P_ID )
)
group by m
M MAX(P)
4 -오길자-김유빈
9 -커-나-김흥수
이런 결과가 나오며 사이클이 검증됩니다.(참고적으로 일단 사이클이
있다는 것은 레벨의미가 없다는 것이구요 '김흥수-커-나' 형태나
'커-나-김흥수','나-김흥수-커' 모두가 우선 순위나 상위 개념이 없는
동등한 결과입니다.)
특징은 여기에는 가장 단순한 계층구조 형태이며 다른 전제조건이
없다는 점입니다.
그런데 제가 납득이 가지 않는 부분은 위의 SQL에서
밑줄친 부분이 connect by 에서 loop가 발견되었습니다라는
에러가 나지 않는다는 점입니다.
아무리 생각해도 다른 조건이 없으므로 에러가 나야 정상일 것 같은데....
안납니다.
또한 위의 SQL은 in으로도 가능한데...
in을 쓸 경우는
Where a.ID in (
select
b.id
from t_hir b
start with
b.p_id = a.ID
connect by
prior b.ID = b.P_ID
)
이런 식이 됩니다.
마찬가지로 에러가 나야 정상인것 같은데.....
안납니다.
왜 에러가 안나는지에 대해 속 시원히 답을 주실 분을
기다리겠습니다.
^^
|