2012-04-05 160 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))