2012-04-05 2 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 fk?Ограничение проверки PostgreSQL

+0

Да, но это может быть не лучшая идея. –

ответ

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))
Смежные вопросы