Ограничение для столбцов, ссылающихся на себя, на основе значения строки в другом столбце - postgres - PullRequest
0 голосов
/ 26 мая 2020

У меня есть таблица типа

user_id  |     team     |   role   | reports_to
___________________________________________
lion       carnivore      manager    
tiger      carnivore      lead       lion
cheetah    carnivore      player     tiger
deer       herbivore      player     tiger
CREATE TABLE team(
    user_id TEXT NOT NULL,
    team_name TEXT NOT NULL,
    role TEXT NOT NULL,
    reports_to TEXT,

    CONSTRAINT teampk PRIMARY KEY (user_id),
    CONSTRAINT public_team_name_team CHECK (team_name = ANY (ARRAY['carnivore'::text, 'herbivore'::text])),
    CONSTRAINT public_team_name_role CHECK (role = ANY (ARRAY['manager'::text, 'lead'::text, 'player'::text])),
    CONSTRAINT teamfk_team FOREIGN KEY (reports_to)
        REFERENCES team(user_id)
);

Могу ли я установить другое ограничение для FOREIGN KEY, чтобы проверить, что reports_to будет либо manager, либо lead?

1 Ответ

1 голос
/ 26 мая 2020

Вы не можете создать внешний ключ для этой проверки, но вы можете создать ограничение проверки с функцией для этого:

create function f_check_reports_to(p_user_id text) returns boolean
language plpgsql
as
$$
declare
v_role text;
begin
 select role into v_role from team where user_id = p_user_id;
 if (v_role = 'manager' or v_role = 'lead' or v_role is null)
 then return true;
 else return false; 
 end if;
end;
$$;
CREATE FUNCTION

alter table team add constraint check_reports_to check(f_check_reports_to(reports_to));
ALTER TABLE

insert into team values('lion', 'carnivore', 'manager', null);
INSERT 0 1
insert into team values('tiger', 'carnivore', 'lead', 'lion');
INSERT 0 1
insert into team values('cheetah', 'carnivore', 'player' ,'tiger');
INSERT 0 1
insert into team values('deer', 'herbivore', 'player', 'tiger');
INSERT 0 1

select * from team;
 user_id | team_name |  role   | reports_to 
---------+-----------+---------+------------
 lion    | carnivore | manager | 
 tiger   | carnivore | lead    | lion
 cheetah | carnivore | player  | tiger
 deer    | herbivore | player  | tiger
(4 rows)

insert into team values('KO','KO','player','cheetah');
ERROR:  new row for relation "team" violates check constraint "check_reports_to"
DETAIL:  Failing row contains (KO, KO, player, cheetah).

update team set reports_to='cheetah' where user_id='tiger';
ERROR:  new row for relation "team" violates check constraint "check_reports_to"
DETAIL:  Failing row contains (tiger, carnivore, lead, cheetah).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...