2012-04-05 125 views
1
CREATE TABLE my_table 
(
    fk  INTEGER, 
    field_1 INTEGER, 
    field_2 INTEGER, 
    field_3 INTEGER 
) 

VALID: 

    fk | field_1 | field_2 | field_3    
----------+---------------+---------------+--------------- 
    1 |  1  |  null  |  null 
    1 |  null  |  1  |  null 
    1 |  null  |  null  |  1 

可以創建檢查約束,它只允許1個字段爲3,對於1個字符可以不爲null?PostgreSQL檢查約束

+0

是的,但是這可能不是最好的主意。 – 2012-04-05 11:03:33

回答

1

這不是很清楚你想達到的目標。

如果你只需要一列是NOT NULL每行,然後Nitram的回答會做,你也可以嘗試:

CHECK ((sign(coalesce(field_1,0)) + 
     sign(coalesce(field_2,0)) + sign(coalesce(field_3,0))) <= 1) 

否則,如果你需要有佔全部行唯一的單NOT NULL柱與給定FK,你應該看看CONSTRAINT TRIGGER,像這樣:

CREATE OR REPLACE FUNCTION only_one() RETURNS trigger AS $only_one$ 
DECLARE 
    cnt int4; 
BEGIN 
    SELECT sign(coalesce(field_1,0)) + 
      sign(coalesce(field_2,0)) + 
      sign(coalesce(field_3,0)) + 
      sign(coalesce(NEW.field_1,0)) + 
      sign(coalesce(NEW.field_2,0))+ 
      sign(coalesce(NEW.field_3,0)) 
     INTO cnt 
     FROM my_table WHERE fk = NEW.fk; 

    IF cnt > 1 THEN 
     RAISE EXCEPTION 'Sorry, too much NOT NULL values for FK=%', NEW.fk; 
    END IF; 

    RETURN NEW; 
END; 
$only_one$ LANGUAGE plpgsql; 
CREATE CONSTRAINT TRIGGER my_table_only_one 
AFTER INSERT OR UPDATE ON my_table 
    FOR EACH ROW EXECUTE PROCEDURE only_one(); 
2

的直接的方式浮現在腦海中:

CHECK ((field_1 IS NOT NULL AND field_2 IS NULL AND field_3 IS NULL) OR 
     (field_2 IS NOT NULL AND field_1 IS NULL AND field_3 IS NULL) OR 
     (field_3 IS NOT NULL AND field_1 IS NULL AND field_2 IS NULL))