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

可以创建检查约束,它只允许 3 中的 1 个字段对于 1 fk 不能为空?

4

2 回答 2

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))
于 2012-04-05T10:55:40.533 回答
1

目前还不太清楚你想要实现什么。

如果您NOT NULL每行只需要一列,那么 Nitram 的答案就可以了,您也可以尝试:

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

否则,如果您需要给定 FK 的每行只有一NOT NULL列,您应该查看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();
于 2012-04-05T20:56:46.277 回答