Я должен был заполнить поле is_continued_post, если выполняются некоторые условия для ранее вставленной строки в таблицу (это тот же пользователь, и его inserted_at меньше N минут от новых строк Insert_at).

Когда новый комментарий вставлен в базу данных. Я хочу получить последний комментарий (с тем же post_id), который был вставлен, затем проверить, что старые строки user_id совпадают с новыми строками user_id, и что старая строка была вставлена ​​менее чем за 2 минуты до новая строка. Если это правда, я хочу перевернуть логическое значение в новой строке на true, прежде чем вставлять его.

Возможно ли это с триггерами Postgresql? Или есть способ лучше?

Вот что я до сих пор придумал:

CREATE OR REPLACE FUNCTION update_message_cont()
RETURNS trigger AS $$
BEGIN
  old := (SELECT m0.user_id, m0.inserted_at FROM messages AS m0 WHERE (m0.post_id = NEW.post_id) ORDER BY m0.inserted_at DESC LIMIT 1);
  NEW.is_continued := CASE
      WHEN old is NULL THEN FALSE
      WHEN old.user_id = NEW.user_id AND ((NEW.inserted_at - old.inserted_at) < 120) THEN TRUE
  END;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;
0
Peter R 15 Июн 2020 в 07:43

1 ответ

Лучший ответ

Да, это возможно, но только если у вас есть столбец в таблице, позволяющий идентифицировать последнюю вставленную строку. Порядок вставки не отражается в таблице как таковой.

Итак, введите столбец

inserted_at timestamp with time zone DEFAULT clock_timestamp() NOT NULL

Индекс на (post_id, inserted_at) сделает запрос быстрым.

Весь триггер может выглядеть так:

CREATE FUNCTION update_message_cont() RETURNS trigger AS
$$BEGIN
   SELECT user_id IS NOT DISTINCT FROM NEW.user_id INTO NEW.is_continued
   FROM messages
   WHERE post_id = NEW.post_id
     AND inserted_at > NEW.inserted_at - INTERVAL '120 seconds'
   ORDER BY inserted_at DESC
   LIMIT 1;

   -- if no previous row was found:
   IF NEW.is_continued IS NULL THEN
      NEW.is_continued = FALSE;
   END IF;

   RETURN NEW;
END;$$ LANGUAGE plpgsql;

CREATE TRIGGER update_message_cont BEFORE INSERT ON messages
   FOR EACH ROW EXECUTE PROCEDURE update_message_cont();
2
Laurenz Albe 15 Июн 2020 в 08:05