Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 1
Регистрация: 07.11.2017
Сообщений: 25

Правило для INSERT на представление, связывающее таблицы, наследующие друг от друга

24.04.2019, 12:02. Показов 1128. Ответов 1

Студворк — интернет-сервис помощи студентам
У меня был большой опыт работы с Firebird, а с PostgreSQL только начинаю работать. С правилами я никогда не работала, а сейчас возникла необходимость создания правил для представлений.
У меня в БД есть несколько таблиц(например,common_data(базовая сущность),location(местоположение) и flat(квартира)), которые наследуют друг от друга (т.е.значение ключ у них должно быть одно и то же).
У меня создано представление, в котором эти таблицы соединяются(v_flat_change). Я хочу сделать правила на изменение данных этого представления. С правилами на UPDATE и DELETE я разобралась, а с правилом на INSERT у меня загвоздка.
Ниже привожу скрипт на создание таблиц, представление и правила.
Если создавать через триггер (на таблицу flat, то мне надо будет в таблице flat дублировать поле id_user (для того, чтобы потом его передать дальше в таблицу common_data). А у меня есть таблицы содержащие намного больше полей и наследующие друг от друга.
Буду признательна,если поможете с этим вопросом.
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
CREATE SCEMA common;
CREATE SCEMA address;
 
CREATE TABLE common.entity_classes (
  id_entity serial NOT NULL PRIMARY KEY,
  id_parent public.dm_small_id,
  title VARCHAR(100) NOT NULL,
  short_name VARCHAR(100) NOT NULL,
  sysname VARCHAR(132) NOT NULL,
  schema_name VARCHAR(15) NOT NULL,
  description VARCHAR(255),
  full_name VARCHAR(120),
   CONSTRAINT pk_entity_classes
    PRIMARY KEY (id_entity),
  CONSTRAINT fk_entity_classes
    FOREIGN KEY (id_parent)
    REFERENCES common.entity_classes(id_entity)
    ON UPDATE CASCADE
)
CREATE TABLE common.common_data (
  id_common bigserial NOT NULL PRIMARY KEY,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  user_create INT8,
  updated_at TIMESTAMP,
  user_update INT8,
  deleted_at TIMESTAMP,
  user_delete INT8,
  id_entity public.dm_small_id NOT NULL,
  CONSTRAINT pk_common_data
    PRIMARY KEY (id_common),
  CONSTRAINT fk_common_data_ref_entity
    FOREIGN KEY (id_entity)
    REFERENCES common.entity_classes(id_entity)
    ON DELETE RESTRICT
    ON UPDATE CASCADE
);
 
CREATE TABLE address.location (
  id_location public.dm_common_id NOT NULL PRIMARY KEY,
  location_type public.dm_common_id NOT NULL,
  address VARCHAR(250),
  CONSTRAINT pk_location
    PRIMARY KEY (id_location),
  CONSTRAINT fk_location_link_common_data
    FOREIGN KEY (id_location)
    REFERENCES common.common_data(id_common)
    ON DELETE RESTRICT
    ON UPDATE RESTRICT
);
 
CREATE TABLE address.flat (
  id_flat public.dm_common_id NOT NULL PRIMARY KEY,
  id_entrance public.dm_common_id NOT NULL,
  NUMBER public.dm_flat_number NOT NULL,
  letter VARCHAR(7),
  number_floor public.dm_number_floor,
  note public.dm_note,
  id_user public.dm_common_id,
  CONSTRAINT pk_flat
    PRIMARY KEY (id_flat),
  CONSTRAINT fk_flat_ref_location
    FOREIGN KEY (id_flat)
    REFERENCES address.location(id_location)
    ON DELETE RESTRICT
    ON UPDATE CASCADE
);
 
CREATE VIEW address.v_location_change
AS
SELECT
  l.id_location,
  l.location_type,
  COALESCE(user_delete,user_update,user_create) AS user_id,
  COALESCE(deleted_at,updated_at,created_at) AS date_at,
   CASE
 WHEN NOT( deleted_at IS NULL)
 THEN 'D'
 WHEN NOT(updated_at IS NULL)
 THEN 'U'
 ELSE 'I'
 END operation
FROM address.location l
  JOIN common.common_data c ON l.id_location=c.id_common;
 
CREATE VIEW address.v_flat_change
AS
SELECT
  f.id_flat,
  f.id_entrance,
  f.number AS flat_number,
  f.letter,
  f.number_floor,
  l.location_type,
  l.user_id,
  l.date_at,
  l.operation
FROM (address.v_location_change l
  JOIN address.flat f ON l.id_location=f.id_flat;
 
CREATE RULE v_flat_update AS
ON UPDATE TO address.v_flat_change DO INSTEAD (
    UPDATE address.flat
    SET id_entrance=NEW.id_entrance,
         NUMBER=NEW.flat_number ,
         letter=NEW.letter ,
         number_floor=NEW.number_floor
    WHERE id_flat=OLD.id_flat;
    UPDATE common.common_data
    SET updated_at = CURRENT_TIMESTAMP,
        user_update = NEW.user_id
    WHERE id_common=OLD.id_flat;
);
 
CREATE RULE v_flat_delete AS
ON DELETE TO address.v_flat_change DO INSTEAD (
    UPDATE common.common_data
    SET deleted_at = CURRENT_TIMESTAMP,
        user_delete = OLD.user_id
    WHERE id_common=OLD.id_flat;
);
А вот правило на вставку создавать не хочет. Ругается на то, что переменная id_common в последнем INSERT (в таблицу flat) не определена:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CREATE RULE v_flat_insert AS
ON INSERT TO address.v_flat_change DO INSTEAD (
 
    WITH es AS
    (SELECT id_entity
     FROM common.entity_classes
     WHERE full_name='address.flat'
     RETURNING *
    )
    INSERT INTO common.common_data
      (id_common,user_create, id_entity)
      VALUES
      (NEXTVAL('common.common_data_id_common_seq'),NEW.user_id,es.id_entity)
      RETURNING id_common;
    INSERT INTO address.location
      (id_location,location_type)
      VALUES
      (id_common,NEW.location_type);
    INSERT INTO address.flat
      (id_flat,id_entrance,NUMBER,letter,number_floor)
      VALUES
      (id_common,NEW.id_entrance,NEW.flat_number,
       NEW.letter,NEW.number_floor);
);
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.04.2019, 12:02
Ответы с готовыми решениями:

Представление нескольких зависящих друг от друга таблиц на форме
Привет всем. Я уже несколько давно не возвращался к этой теме, на счет работы с базами данных на C#, но тут опять возникла нужда. Думаю Вы...

Представление в виде строки, где триады цифр отделены друг от друга пробелами
Здравствуйте, задача такова: для заданного натурального числа n получить его правильное символьное представление в виде строки ...

Как в PHP отделить элементы друг от друга, чтобы не ругались друг на друга?
<?php $chitat = fopen('yoo.txt', 'r'); if (!$chitat) { echo 'Ошибка при открытии файла yoo.txt'; } while (false !== ($char =...

1
0 / 0 / 1
Регистрация: 07.11.2017
Сообщений: 25
25.04.2019, 09:32  [ТС]
Мне подсказали решение (я не знала о функции CURRVAL в PostgreSQL):
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CREATE OR REPLACE RULE v_flat_insert AS
 
ON INSERT TO address.v_flat_change DO INSTEAD (
 
    WITH es AS
    (SELECT id_entity
     FROM common.entity_classes
     WHERE full_name='address.flat'
    )        
    INSERT INTO common.common_data
      (id_common,user_create, id_entity)
      VALUES
      ( NEXTVAL('common.common_data_id_common_seq'), NEW.user_id, ( SELECT id_entity FROM es LIMIT 1));
    WITH lt AS
    (SELECT id
     FROM address.dict_location_type
     WHERE sysname='FLAT'
    )        
    INSERT INTO address.location
      (id_location,location_type)
      VALUES
      ( CURRVAL('common.common_data_id_common_seq'),( SELECT id FROM lt LIMIT 1));--new.location_type
    INSERT INTO address.flat
      (id_flat,id_entrance,NUMBER,letter,number_floor)
      VALUES
(CURRVAL('common.common_data_id_common_seq'),NEW.id_entrance,NEW.flat_number,
       NEW.letter,NEW.number_floor);
);
Добавлено через 42 секунды
разместило решение здесь, может кому поможет
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.04.2019, 09:32
Помогаю со студенческими работами здесь

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

Реализовать пакетную вставку в БД (MS SQL) в зависимые друг от друга таблицы
Доброго времени суток, форумчане! Подскажите пожалуйста как можно реализовать пакетную вставку в БД (MS SQL) в зависимые друг от друга...

Найти слова, которые являются анаграммами друг для друга
Анагра́мма (от греч. ανα- — «пере» и γράμμα — «буква») — литературный приём, состоящий в перестановке букв или звуков определённого слова...

Выписать все слова, которые являются анаграммами друг для друга
Анагра́мма (от греч. ανα- — «пере» и γράμμα — «буква») — литературный приём, состоящий в перестановке букв или звуков определённого слова...

Разработать программу для нахождения пары самых удаленных друг от друга точек
N точек на плоскости заданы своими координатами, значения которых формируются случайным образом. Значение N вводится пользователем....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru