#sql #postgresql #triggers #plpgsql
#sql #postgresql #триггеры #plpgsql
Вопрос:
Я работаю с этой базой данных … в основном мне нужно создать триггер «promote_cyclist», чтобы запомнить подходящих спортсменов (которые занимают первое место на этапе Джиро д’Италия) в таблице mesh.
Таблицы:
- cyclist (cyclist_id: Int, name_cyclist: строка, команда: строка из трех букв, страна: строка из трех букв)
- лента (_name: строка, km: int, тип: ‘flat’ или ‘high_mountain’ или ‘medium_mountain’ или ‘chronometro_a_team’ или ‘chronometro_individual’ или ‘time_trial’)
- arrival_order (cyclist_id:int ; tape_name:строка, порядок: int): где cyclist_id (соответственно, tape_name) — это внешний ключ, который ссылается на cyclist (соответственно, tape);
- magliarosa( имя: строка);
это триггер, который я загружаю в оболочку…
CREATE FUNCTION promote_cyclist()
RETURNS TRIGGER AS
$
BEGIN
INSERT INTO magliarosa
SELECT c.name_cyclist
FROM cyclist c
WHERE new.cyclist_id = c.cyclist_id AND
new.order = 1;
RETURN NULL;
END ;
$
LANGUAGE plpgsql;
Это команда, которую я передаю в оболочку:
CREATE TRIGGER promote_cyclist
BEFORE INSERT ON arrival_order
EXECUTE PROCEDURE promote_cyclist ();
После загрузки текстового файла arrival_order имена велосипедистов, выигравших хотя бы один этап, должны быть записаны в именах в magliarosa. Однако этого не происходит. Не могли бы вы мне помочь?
Комментарии:
1. вы пропускаете предложение
FOR EACH ROW
вCREATE TRIGGER
инструкции
Ответ №1:
Вы создали ТРИГГЕР BEFORE, поэтому он срабатывает до того, как ВСТАВКА действительно произойдет. Но RETURN NULL сообщает базе данных заменить НОВУЮ полезную нагрузку на NULL.
Попробуйте ВЕРНУТЬ НОВЫЙ;
Комментарии:
1. спасибо, я добавил «для каждой строки» и изменил возврат… теперь кортежи вставляются в ‘Magliarosa’, но может случиться так, что если велосипедист выигрывает более одного этапа, его имя присутствует несколько раз в ‘Magliarosa’. … Я думал, что простого ‘SELECT DISTINCT c.cyclist_name’ в функции ‘promote_cyclist’ было достаточно, но это не так … как я могу решить проблему?
2. Когда имя должно быть там только один раз, я бы использовал уникальное ограничение и убедился, что вставка будет проверять наличие конфликтов: ПРИ КОНФЛИКТЕ НИЧЕГО НЕ ДЕЛАТЬ
3. хорошо, итак, в основном рядом с «именем» я ставлю «УНИКАЛЬНЫЙ» …. «ПРИ КОНФЛИКТЕ НИЧЕГО НЕ ДЕЛАТЬ», где я должен это написать?
4. Да, УНИКАЛЬНОЕ ограничение может быть создано при создании таблицы, создании уникального индекса или создании отдельного уникального ограничения. Все три будут работать нормально. КОНФЛИКТ ON описан в руководстве и показывает несколько примеров: postgresql.org/docs/13/sql-insert.html#SQL-ON-CONFLICT
5. Насколько я понимаю, его следует использовать с ‘Insert’, но я не использую эту команду для вставки кортежей… Я использую copy … что мне делать?