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 fk不为空吗?
答案 0 :(得分: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))
答案 1 :(得分: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();