2017-04-22 3 views
3

oracle sql 스크립트를 만드는 데 문제가 있습니다. 이 두 가지 제약 조건을 어떻게 만듭니 까?Oracle sql 제약 조건 질문

  1. VID가 null 다음 FID 널뿐만되어야한다면 (VID = NULL -> FID = NULL)
  2. 또한 FID가되어야한다는 것을 의미 VID가 null 정확히 하나 개의 행이 있어야만 널 (null) 때문에 1. 다음

는 내가 지금까지 무엇을 가지고의 :

create table Employee(
Id int primary key, 
Name varchar(15) not null, 
VID int, 
FID int 

); 

Employee

+0

"스크립트"란 무엇을 의미합니까? (나는 아무것도 생각하지 않는다. 당신은 기술적 인 의미에서이 단어를 사용하지 않는다. 그러나 내가 틀렸다면 설명해 주라.) 그런 다음, 첫 번째 제한은 글을 쓰는 것이 쉽지 않다. 마지막으로, 두 번째 조건은 제약 조건과 다른 것은 적용 할 수 없습니다. 제약 조건은 전체 테이블이 아닌 개별 행에 대한 조건입니다. 고든 (Gordon)이 말한 한 가지 해결책은 방아쇠 일 수 있습니다. 또 하나는 커밋시 빠른 새로 고침을 사용하여 구체화 된 뷰를 생성하는 것인데, 이는 머티리얼 화 된 뷰에 대한 제약 조건과 함께 VID에 null 개수를 저장하는 것입니다. – mathguy

답변

0

방아쇠를 당기지 않고 원하는 곳에 아주 가까이 다가 갈 수 있습니다.

첫 번째에 대한 점검 제한 조건을 사용할 수 있습니다

create unique index unq_Employee_vid on 
    Employee(case when vid is null then -1 else id end); 

이 제제는 id가 대부분으로, 음이 아닌 것을 가정

alter table Employee add constraint chk_vid_fid 
    check (vid is not null or fid is null); 

당신은 고유 제한 조건을 사용하여 두 번째 작업을 수행 할 수 있습니다 일반적으로 ID가 있습니다. 당신이 정수 값의 전체 범위를 사용한다면, 그때는 문자열로 명시 될 것이다 :

create unique index unq_Employee_vid on 
    Employee(case when vid is null then 'null vid' else cast(id as varchar2(255)) end); 

보장 최대vid이 아니라 정확히 한 행 null의 하나의 행. 빈 테이블이 조건과 일치하지 않으며 테이블을 만들 때 테이블이 비어 있기 때문에 정확히 한 행에 값이 있음을 보장하는 제약 조건을 쉽게 가질 수 없습니다.

+1

'-1'은'id' (int라고 선언)에 유효한 값입니다. 이 방법은 유효하지 않은 값 (아마도 '0.5')을 사용하는 것이 더 이상적이지 않습니다. 유효하지 않은 삽입 방법과 충돌하지 않도록 보장됩니다. – mathguy

+0

귀하가 진술 한대로이 솔루션은 OP의 요구 사항을 구현하지 않습니다 **. 방금 구체화 된보기를 사용하여 하나의 솔루션을 게시했습니다. – mathguy

0

여기에 정확히 한 행 VID is NULL을 적용하는 방법이 있습니다. 내가 원래의 질문에 대한 나의 코멘트에서 말했듯이 (그리고 고든은 그의 대답에서 대답했다.) 제약 조건만으로는 이것을 할 수 없다. 그러나 구체화 된보기로이를 수행 할 수 있습니다. refresh fast on commit으로 MV를 작성해야하며 기본 표의 구체화 된보기 로그에 대해 특정 사항이 필요합니다.

또한 : 정확히 작성된 모든 것을하려고하면 (기본 테이블이 비어 있기 때문에, 물론, 그래서 VIDNULL 여기서 더 행이 없을 것), 뮤직 비디오에 제약이 실패합니다. 정확히 하나의 테이블에 VIDNULL이있는 행을 추가 한 다음 commit 트랜잭션을 추가하고 alter table 명령을 실행하여 MV에 제약 조건을 추가합니다. 그리고 그것은 VID 열에서 NULL에 정확히 하나 개의 행을 남긴다 경우에만 경우 그 시점부터 (한 commit 다음에 하나 이상의 insert, delete, update 또는 merge 문으로 구성) 기본 테이블에 거래를 통해 이동합니다.

오라클 SQL에 ALTER MATERIALIZED VIEW 문이 있어도 MV에 제약 조건을 추가하려면 ALTER MATERIALIZED VIEW이 아닌 ALTER TABLE 문 (MV 이름 포함)을 사용해야합니다.

이미 테이블 EMPLOYEE이 있었기 때문에 t_Employee이라는 이름을 사용했습니다. 기존 개체를 망치고 싶지는 않습니다.

create table t_Employee(
Id int primary key, 
Name varchar(15) not null, 
VID int, 
FID int 
); 

alter table t_Employee add constraint chk_vid_fid 
    check (vid is not null or fid is null) 
; 

create materialized view log on t_Employee 
with rowid 
(VID) 
including new values 
; 

create materialized view mv_Employee 
refresh fast on commit 
as select count(*) ct 
    from t_Employee 
    where VID is null 
; 

alter table mv_Employee add constraint chk_vid_ct 
    check (ct = 1) 
;