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つのフィールドのみが1fkに対してnullにならないことを許可するチェック制約を作成することは可能ですか?

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

何を達成したいのかははっきりしていません。

行ごとに1つの列だけが必要な場合はNOT NULL、Nitramの答えで十分です。次のことも試してみてください。

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

それ以外の場合、NOT NULL指定されたFKのすべての行に1つの列のみが必要な場合は、次の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 に答える