Как вставить обязательно разные значения в 2 таблицы, которые имеют только один атрибут и имеют один и тот же внешний ключ? - PullRequest
0 голосов
/ 06 мая 2019

Итак, у меня есть таблица 'category', которая разделяется на 'simple_category' и 'super_category'. Категория имеет только один атрибут, который является ее именем. То же самое происходит с двумя другими таблицами, которые имеют ограничение внешнего ключа для имени. Super_category и simple_category не могут иметь одно и то же имя. Как мне это сделать?

create table category(
    name varchar(20) not null,
    unique(name),
    primary key(name));

create table simple_category(
    name varchar(20),
    unique(name),
    primary key(name),
    foreign key(name) references categoria(name));

create table super_category(
    name varchar(20),
    unique(name),
    primary key(name),
    foreign key(name) references categoria(name));

Я ожидаю сообщение об ошибке при попытке вставить равные значения в super_category и simple_category

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

Это будет триггер ограничения, проверяющий наличие имени в другой таблице.

CREATE FUNCTION tf_simple_category_biu ()
                RETURNS TRIGGER
AS
$$
BEGIN
  IF EXISTS (SELECT *
                    FROM super_category sc
                    WHERE sc.name = new.name) THEN
    RAISE EXCEPTION '%', 'Duplicate names are not allowed.';
    RETURN NULL;
  END IF;
  RETURN new;
END;
$$
LANGUAGE plpgsql;

CREATE CONSTRAINT TRIGGER simple_category_biu
                          AFTER INSERT
                                 OR UPDATE
                                    OF name
                          ON simple_category
                          FOR EACH ROW
                          EXECUTE PROCEDURE tf_simple_category_biu();

CREATE FUNCTION tf_super_category_biu ()
                RETURNS TRIGGER
AS
$$
BEGIN
  IF EXISTS (SELECT *
                    FROM simple_category sc
                    WHERE sc.name = new.name) THEN
    RAISE EXCEPTION '%', 'Duplicate names are not allowed.';
    RETURN NULL;
  END IF;
  RETURN new;
END;
$$
LANGUAGE plpgsql;

CREATE CONSTRAINT TRIGGER super_category_biu
                          AFTER INSERT
                                 OR UPDATE
                                    OF name
                          ON super_category
                          FOR EACH ROW
                          EXECUTE PROCEDURE tf_super_category_biu();

db <> fiddle

0 голосов
/ 06 мая 2019

Ну, один из методов - это триггер.Другой метод заключается в том, чтобы поместить тип в таблицу категорий и включить его в отношения внешнего ключа:

create table category (
    category_id serial primary key,
    name varchar(20) not null,
    type varchar(20) not null,
    check type in ('super', 'simple'),
    unique (name),
    unique (type, name)  -- redundant but needed for foreign key reference
);

create table simple_category (
    category_id serial primary key,
    type varchar(20) default 'simple',
    foreign key (type, category_id) references categoria (type, category_id)
);

create table super_category (
    category_id serial primary key,
    type varchar(20) default 'super',
    foreign key (type, category_id) references categoria (type, category_id)
);

Обратите внимание, что я также изменил таблицы, добавив в них первичные ключи с автоинкрементом, чтобы имена не повторялись везде.

Как это работает?Сначала вставьте категорию в categoria с соответствующим типом.Затем вставьте ссылку в соответствующую таблицу.Вы можете сделать второе с помощью триггера.Однако я предполагаю, что вам нужна другая информация, поэтому они разбиты на разные таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...