PostgreSQL НА ВСТАВКУ КАСКАДА - PullRequest
0 голосов
/ 20 ноября 2011

У меня есть две таблицы - одна - Product, а другая - ProductSearchResult.

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

Я хотел бы знать, как я могу заставить мою базу данных автоматически создавать этот отсутствующий Продукт в Таблице продуктов (Только ProductID, все остальные атрибуты можно оставить пустыми)

Есть ли такая вещь, как CASCADE ON INSERT? Если есть, я не смог заставить его работать.

Правила выполняются после вставки, поэтому, поскольку мы заранее получаем ошибку, бесполезно, если вы используете «DO ALSO». Если вы используете «DO INSTEAD» и добавляете команду «INSERT» в конце, вы получаете бесконечную рекурсию.

Я считаю, что Триггер - это путь, но все мои попытки написать один провалились.

Есть рекомендации?

Структура таблицы:

CREATE TABLE Product (
    ID char(10) PRIMARY KEY,
    Title varchar(150),
    Manufacturer varchar(80),
    Category smallint,
    FOREIGN KEY(Category) REFERENCES Category(ID) ON DELETE CASCADE);


CREATE TABLE ProductSearchResult (
    SearchTermID smallint NOT NULL,
    ProductID char(10) NOT NULL,
    DateFirstListed date NOT NULL DEFAULT current_date,
    DateLastListed date NOT NULL DEFAULT current_date,
    PRIMARY KEY (SearchTermID,ProductID),
    FOREIGN KEY (SearchTermID) REFERENCES SearchTerm(ID) ON DELETE CASCADE,
    FOREIGN KEY (ProductID) REFERENCES Product ON DELETE CASCADE);

Ответы [ 2 ]

2 голосов
/ 20 ноября 2011

Да, триггеры - это путь.Но прежде чем вы сможете начать использовать триггеры в plpgsql, вы должны включить язык.Как пользователь postgres, запустите команду createlang с правильными параметрами.

После того, как вы это сделаете, вы должны

  1. Написать функцию в plpgsql
  2. создать триггер для вызова этой функции

См. пример 39-3 для базового примера.

Обратите внимание, что тело функции в Postgresстрока со специальным механизмом цитирования: 2 знака доллара с необязательным словом между ними, как кавычки.(Слово позволяет вам заключать в кавычки другие аналогичные кавычки.)

Также обратите внимание, что вы можете повторно использовать процедуру триггера для нескольких таблиц, если в них есть столбцы, используемые вашей процедурой.

Так чтофункция должна

  1. проверить, существует ли значение NEW.ProductID в таблице ProductSearchResult, с оператором выбора (вы должны иметь возможность использовать SELECT count(*) ... INTO someint или SELECT EXISTS(...) INTO somebool)
  2. если нет, вставьте новую строку в эту таблицу

Если вы все еще застряли, вернитесь сюда.

0 голосов
/ 20 ноября 2011

В любом случае (правила ИЛИ триггеры) вставка должна создать новый ключ (и новые значения для атрибутов) в таблице продуктов.В большинстве случаев это подразумевает, что суррогатный первичный ключ (последовательный, последовательный) должен использоваться в таблице продуктов, и что «реальный мир» product_id («номер продукта») должен по умолчанию иметь значение NULL и быть понижен до ключа-кандидата..

Кстати: правило можно использовать , правила просто сложны для правильной реализации для отношений N: 1 (им нужен такой же тип EXISTS-логики, как в ответе Барта выше).

Может быть, каскадирование на INSERT не очень хорошая идея в конце концов.Что вы хотите случиться, если кто-то вставит запись ProductSearchResult для несуществующего продукта?[IMO FK - это всегда домен;вы не можете просто расширить домен, просто сославшись на несуществующее значение для него;это сделало бы ограничение FK бессмысленным]

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