두 칼럼 범위를 제약조건으로 지정할 수 있을까요? 0 4 2,862

by 커피요쿠르트d [Oracle 기초] 유니크 년도범위 제약조건 pk [2013.11.15 16:44:56]


수고하십니다. 
테이블 그려보다 궁금한 점이 있어 질문드립니다. 

with tbl as(
select 'AA' CODE , '2010' START_YEAR, '2011' END_YEAR, 'ETC VALUE' ETC FROM DUAL UNION ALL
select 'AA' CODE , '2012' START_YEAR, '2013' END_YEAR, 'ETC VALUE' ETC FROM DUAL UNION ALL
select 'AA' CODE , '2014' START_YEAR, '2015' END_YEAR, 'ETC VALUE' ETC FROM DUAL UNION ALL
select 'BB' CODE , '2013' START_YEAR, '2015' END_YEAR, 'ETC VALUE' ETC FROM DUAL UNION ALL
select 'CC' CODE , '2013' START_YEAR, '2015' END_YEAR, 'ETC VALUE' ETC FROM DUAL 
)SELECT * FROM TBL





위와 같은 테이블에서 CODE, START_YEAR ~ END_YEAR (범위)를 제약조건으로 할 수 있을까요?

예를 들어 위와 같은 상황에서 
 
INSERT INTO TBL (CODE, START_YEAR, END_YEAR, ETC ) VALUES( 'BB', '2012' , '2014' , 'ETC' ) ;
INSERT INTO TBL (CODE, START_YEAR, END_YEAR, ETC ) VALUES( 'BB', '2014' , '2016' , 'ETC' ) ;
INSERT INTO TBL (CODE, START_YEAR, END_YEAR, ETC ) VALUES( 'BB', '2013' , '2013' , 'ETC' ) ;


이런 자료들이 안들어가는 제약입니다. 
모두 BB 의 범위인 2013 ~ 2015년도 범위를 침해(??) 하는 년도 정보를 입력할려는 시도입니다. 

물론 입력단계에서 체크하고, 입력값을 체크하는 트리거도 해놓을 생각인데요. 
명시적으로 알 수 있게 제약조건을 걸 수 있는 방법이 있을까요?
오라클에서 이런 것도 가능할 까요? ㅋ


혹시 가능하다면 알려주시면 감사하겠습니다. 

아.. 그리고 추가로..

제약조건과 별개로 ...
PK를 잡아야 할건데요..
이런 경우는 PK를 어떻게 잡아야할까요?
CODE, START_YEAR만 잡으면 되는지..
CODE, START_YEAR, END_YEAR를 잡으면 되는지...


아.. DB는 오라클 10g입니다~~

그럼 즐거운 오후 되셔요..

아.. 금요일 오후였네요.. ㅠㅠ 흑흑 목요일인줄 알고 있었다는..
불금 되시길..     
by 마농 [2013.11.16 12:38:26]
-- 제약조건이나 트리거로는 힘들 듯 합니다.
-- 어플 단계에서 체크하세요.
SELECT COUNT(*)
  FROM tbl
 WHERE code = :v_code
   AND start_year <= :v_end_year
   AND end_year   >= :v_start_year
;

by 커피요쿠르트d [2013.11.19 21:36:56]
알려주신대로 진행하고 있습니다. 
감사합니다~!!!

by Oracler [2013.11.17 15:22:50]
입력값의 범위를 제한하려는 제약조건이면 일반적으로 CHECK 제약일텐데 문제의 성격상 CHECK로는 구현할 수 없습니다.

다음으로 가능한 방법으로 트리거를 사용하여 마치 DB의 제약조건의 논리를 구현할 수 있습니다.
하지만 질문의 문제와 같이 DML이 되려는 테이블의 내용을 트리거에서 SELECT 또는 DML하게 되면 해당 테이블이 Mutating Table이 되어 트리거 자체가 컴파일이 되지 않습니다.

오라클 11g라면 복합 트리거(Compound Trigger)를 사용하여 해결할 수 있습니다만 10g 를 사용하신다니 이 방법도 안되겠군요.

해결하시려면 마농님 말씀처럼 애플리케이션 단에서 처리하던지 tbl 테이블의 내용을 정리하여 코드별 시작년도와 종료년도를 저장한 새로운 테이블(예제의 tbl을 보니 코드 'AA'의 경우 행이 3개네요, 이것을 하나로 정리한 새로운 테이블) 을 만든 다음 tbl 테이블의 INSERT BEFORE 행 트리거에서 새로운 테이블을 참조하여 처리하는 방식으로 하면 될 것입니다.

by 커피요쿠르트d [2013.11.19 21:37:47]
자세한 설명 정말 감사합니다!!!

마농님께서 알려주신 방법대로 진행하려 합니다. 

정말 감사합니다.~~
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입