SQL: написать триггер, который останавливает вставку строки, если Person уже владеет хранилищем - PullRequest
0 голосов
/ 04 мая 2019

У меня есть следующая таблица с именем Manager:

Store   |   Person
ABC         Ms. Elara
XYZ         Mr. Saros
DEF         Ms. Orion

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

Мой подход заключается в том, что в функции триггера вы выбираете кортежи из таблицы Manager, где Person равен Person в кортеже, который вы пытаетесьвставить.Если в таблице Manager есть кортежи, в которых Person равен Person в новом добавляемом кортеже, строка не будет вставлена.

Я не уверен, как в функции триггера я могу выбратьвсе кортежи от менеджера, где человек равен человеку, который будет вставлен.Любые идеи приветствуются.

Ответы [ 2 ]

3 голосов
/ 04 мая 2019

Вы также можете использовать уникальный индекс:

CREATE UNIQUE INDEX Manager_IDX ON Manager (person);

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

Вы сказали, что хотите узнать о триггерах, один из способов начать это иметь триггер (фактически 3,вставьте, обновите и удалите триггер) в диспетчере, который автоматически ведет историю изменений (например, контрольный журнал) в другой таблице (например, manager_audit).Таблица аудита будет иметь то же определение, что и таблица Manager, но по крайней мере с одним дополнительным столбцом (например, кодом операции), который отслеживает, какая была операция.например, я для вставки, D для удаления, U для обновления.Вы также можете иметь временную метку для записи, когда произошла операция, и другие поля (например, идентификатор пользователя, который внес изменения и т. Д.).

Сказав все это и во что бы то ни стало, обеспечив уникальность таких вещей, какимя не может быть лучшей идеей.Вполне возможно, что «мистер Смит» может быть именем двух разных людей, которые работают в большой компании.

Еще один фактор, который вы можете рассмотреть, - это производительность.Если вы используете метод выбора на основе, чтобы обеспечить уникальность столбцов / столбцов, не относящихся к индексу, вам потребуется «сканирование всех строк» ​​таблицы для выполнения этого теста.Это будет верно независимо от того, как вы его реализуете (например, триггер, функция, процедура или что-то еще).

Другими словами, допустим, у вас есть 100 менеджеров, и вы хотите вставить нового.Проверка на основе выбора потребует, чтобы вы просмотрели всю таблицу (т.е. 100 строк), чтобы увидеть, существует ли имя уже.По мере роста таблицы сканирование также будет расти.Со временем вы столкнетесь с явлениями «ухудшенной производительности».Когда таблица достигает миллионов или миллиардов строк, ваша «вставка одной записи» фактически потребует миллиардов операций ввода-вывода.

Индексы не работают таким образом.Индексы - это, по сути, инвертированные вложенные таблицы, в которых назначенные вами столбцы (например, manager.person) являются «ключом».Таким образом, для выполнения необходимых проверок потребуется только один ввод / вывод - независимо от того, сколько записей в нем может быть.

отказ от ответственности для пуристов, я определяюВвод-вывод как логический ввод-вывод «на уровне записи», а не физический дисковый ввод-вывод или ввод-вывод любого другого типа.Таким образом, одна запись считывается = 1 ввод / вывод, одна запись записывается = 1 ввод / вывод.

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

Зачем вам для этого триггер?Вы можете написать функцию postgres, которая проверяет существование конкретного человека перед вставкой.

Примерно так:

Create function check_person_exists(par_person_id int)
Declare var_exists_flag int;
Begin
var_exists_flag =0;p

Select 1 from table where person_id = par_person_id into var_exists_flag;
If var_exists_flag = 0
Then
Insert into ....
Else 
Raise notice ' the records already exists';
Return;
End

PS: приведенный выше код будет иметь синтаксические проблемы.

...