Создание триггера SQL для обновления таблиц при вводе данных в представление - PullRequest
0 голосов
/ 29 апреля 2020

Если у меня есть эта настройка:

CREATE TABLE category(
  category_id    serial PRIMARY KEY,
  category_name  text UNIQUE NOT NULL  -- must be UNIQUE
);

CREATE TABLE parts (
  part_id        serial PRIMARY KEY,
  category_id    int REFERENCES product,
  part_name      text
);

CREATE VIEW partview AS
SELECT com.part_id, cat.category_name, com.part_name
FROM   parts com
LEFT   JOIN category cat USING (category_id);

Как создать триггер, чтобы при вставке данных в представление исходные таблицы обновлялись? Я пробовал это ... но это не работает: (

CREATE FUNCTION insert_view_func() 
RETURNS trigger as

$func$
    BEGIN
        INSERT INTO parts (category_name)
        select (select category_id from category where category_name = category.category_name) 
        RETURNING category_id as id
        into new.componentid;

        return new;
    END
$func$ language plpgsql;

create trigger insert_view_trig
INSTEAD of insert on partview 
for each row execute procedure insert_view_func();

1 Ответ

0 голосов
/ 01 мая 2020

Большая проблема с триггерами вставки представления на непростых представлениях - вы не знаете, что вставляется. В этом случае это может быть Категория или Части или оба. Ваш триггер должен обрабатывать оба. Здесь это не является большой проблемой:

create or replace function insert_view_func() 
  returns trigger 
  language plpgsql
as $$
begin
    insert into category (category_name)  values(new.category_name)
      on conflict do nothing; 

    insert into parts (category_id, part_name)
         select category_id, new.part_name 
           from category 
          where category_name = new.category_name;  

    return new;
end ;
$$ ;

Это, однако, не главная проблема здесь. Ваша модель данных устанавливает отношение 1: M между категорией: детали. Не проблема, если вы действительно этого хотите, но это открывает потенциальную проблему. Поскольку Part_Name не уникален, он открывает возможность для нескольких деталей с одинаковым именем (см. fiddle ), но каждая из них связана с отдельной категорией. Это может стать довольно запутанным. Чтобы избежать этого, вы можете рассмотреть отношения M: M и создать таблицу разрешения. Другим вариантом будет изменение функции триггера для проверки существующего part_name. Еще лучше сделать Part_Name уникальным.

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