2011-03-27 25 views
17

Ben Postgresql bir tablo varsa:postgresql bir tek-dışı iki değil boş kısıtının eklenmesi

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) 
); 

Ya schoolName veya studiedAt ihtiyaçları boş olamaz etmek, böylece bir kısıtlamasını yapmak gerekir (bunlardan birinin içinde bilgi olması gerekir).

Bunu nasıl yaparım?

cevap

26

check constraint, örn. kılavuzda itibaren

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

:

bir onay kısıtlaması en genel kısıt türüdür. Belirli bir sütundaki değerin bir Boole (gerçek değer) ifadesini karşıladığını belirtmenize olanak tanır.

Düzenleme: Pithyless' yorumuna uymak Alternatif: Ayrıca güncelleme bir tetikleyici kullanmak ve bir kural tabloya veri izin vermeden önce takip olup olmadığını kontrol etmek ekleyebilirsiniz

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

Bu kontrol, hem okula karşı hem de çalışmayı korumaz ve üzerinde çalışıldığını belirtti. – pithyless

+0

Soru, en azından 'okulAdı' ve 'üzerinde çalışılan' A'nın zorlandığı bir değişkeni soruyor. Sorunun yorumunu kabul etmeme rağmen yorumunuza uyan bir kısıtlama varyantı ekledim. –

+2

Biraz geç, ama bu bir XOR kısıtlamasıdır, böylece 'CHECK ((okul adı NULL) <> (NULL IS NULL))' – norcalli

0

. Normalde, kontrol kısıtlaması daha karmaşık mantığa ihtiyaç duyduğunda bu tür bir yaklaşım kullanırsınız.

+1

uyarısı olarak ifade edebilirsiniz: genellikle bir kısıtlama zorlamak değil tetikleyici –

+0

Bir tetikleyici kullanmaktan ziyade bir kısıtlama uygulamamanın daha iyi olduğunu söylemek için gitmezdim, oposite diyebilirim. Tetik kullanırken daima performansı göz önünde bulundurun ve akıllıca kullanın. Onları bunun için kullanma. Onları özel ihtiyaçlarınız için test edin ve ihtiyaçlarınızı karşılamanıza izin veriyorsa, bunun için gidin. Bir tetikleyici kullanarak doğal kötülük yoktur. Kutuda başka bir araç. – Kuberchaun

+0

Sanırım bu daha önce tartışıldı (http://stackoverflow.com/questions/460316/are-database-triggers-evil). Onlara olan yakınlığım, mevcut veriler üzerinde kurallar uygulamaması ve bunları ateşlemeden veri elde etmek için genellikle yuvarlatmalarıdır (örneğin Oracle için sql * loader). İyi tanımlanmış işlemlere sahip bir API, herhangi bir yan etki olmaksızın daha az veri bütünlüğü sağlamaz (ve çok daha fazla fayda sağlar). –