2011-03-27 3 views
17

내가 PostgreSQL을에 테이블이있는 경우 :PostgreSQL의에서 한 - 아웃 - 오브 -이 NOT NULL 제약 조건을 추가

create table Education ( 
    id     integer references Profiles(id), 
    finished   YearValue not null, 
    started    YearValue, 
    qualification  text, 
    schoolName   text, 
    studiedAt   integer references Organizations(id), 
    primary key (id) 
); 

가 나도 schoolName 또는 studiedAt 필요가 null이 될 수 없습니다 할 수 있도록 제약 조건을 만들 필요를 (그들 중 하나는 그것에 정보가 있어야합니다).

어떻게하면됩니까?

답변

26

예 : check constraint을 사용할 수 있습니다. 수동에서

constraint chk_education check (schoolName is not null or studiedAt is not null) 

:

점검 제한 조건이 가장 일반적인 제약 조건 유형입니다. 이를 통해 특정 열의 값이 부울 (진리 값) 표현식을 충족시켜야 함을 지정할 수 있습니다.

편집 : Pithyless '해석을 준수 대안 : 당신은 또한 업데이트시 트리거를 사용하여 규칙이 테이블에 데이터를 허용하기 전에 다음에 있는지 확인하기 위해 삽입 할 수 있습니다

constraint chk_education check ((schoolName is not null and studiedAt is null) or (schoolName is null and studiedAt is not null)) 
+1

이 수표는 schoolName과 learnedAt가 설정되는 것을 방지하지 않습니다. OP도 염두에 두었습니다. – pithyless

+0

"schoolName"및 "learnedAt"중 적어도 하나가 몇 가지 정보를 포함하도록하는 불변식이 질문됩니다. 질문에 대한 해석에 동의하지 않지만 귀하의 의견을 따르는 제약 조건의 변형을 추가했습니다. –

+2

조금 늦었지 만 이것은 XOR 제약 사항이므로 CHECK ((schoolNAME NULL) <> (learnedAt IS NULL))로 표현할 수 있습니다. – norcalli

0

. 점검 제한 조건이 더 복잡한 논리를 필요로 할 때 일반적으로이 유형의 접근 방식을 사용합니다.

+1

주의 : 제약 조건을 적용하지 않는 것이 좋습니다. trigger –

+0

방아쇠를 쓰는 것보다 제약을 가하지 않는 것이 더 낫다는 말은하지 않을 것입니다. 트리거를 사용할 때는 항상 성능을 명심하고 현명하게 사용하십시오. 그것의 지옥을 위해 그들을 사용하지 마십시오. 특정 요구 사항을 테스트하여 요구 사항을 충족시킬 수 있는지 확인하십시오. 방아쇠를 사용하면 악의가 없습니다. 그것은 상자 안에있는 또 다른 도구입니다. – Kuberchaun

+0

나는 이것 [이전 토론] (http://stackoverflow.com/questions/460316/are-database-triggers-evil)되었습니다 것 같아요. 그들에 대한 나의 불만은 기존 데이터에 대한 규칙을 시행하지 않으며 발사하지 않고 데이터를 가져올 수있는 방법이 종종 있습니다 (예 : Oracle 용 sql * loader). 그렇다면 잘 정의 된 트랜잭션을 가진 API는 부작용없이 데이터 무결성을 제공합니다 (그리고 더 많은 이점이 있습니다) –