2012-04-05 4 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 

Il est possible de créer une contrainte de vérification qui permet à seulement 1 champ de 3 de ne pas être nul pour 1 fk?Contrainte de vérification PostgreSQL

+0

Oui, mais ce n'est peut-être pas la meilleure idée. –

Répondre

1

Il est pas tout à fait clair ce que vous souhaitez réaliser.

Si vous avez besoin une seule colonne étant NOT NULL par ligne, alors la réponse de Nitram fera, vous pouvez aussi essayer:

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

Sinon, si vous avez besoin d'avoir seulement seule colonne NOT NULL par toutes les lignes avec la donnée FK, vous devriez regarder dans le CONSTRAINT TRIGGER, quelque chose comme ceci:

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

La voie à suivre droite viennent à l'esprit:

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))
Questions connexes