postgresql - 如何编写将最后插入的行放入表中的触发器?
问题描述
is_continued_post
如果某些条件是关于先前插入表中的行的某些条件为真,我将填充一个字段(它是同一个用户,并且它inserted_at
距离新行 insert_at 不到 N 分钟)。
将新评论插入数据库时。我想获取插入的最后一条评论(具有相同的post_id
),然后检查旧行 user_id 是否与新行 user_id 相同,并且旧行在新行之前不到 2 分钟插入。如果这是真的,我想在插入之前将新行上的布尔值翻转为真。
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;
解决方案
是的,这是可能的,但前提是您的表中有一个列可以让您识别最后插入的行。插入顺序并未反映在表中。
所以介绍一个专栏
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();
推荐阅读
- c++builder - Borland C++ Builder 6 的 Virtualtreeview
- javascript - 如何在 iframe 完成加载之前覆盖其内的 JavaScript 警报功能?
- path - Phoebe GUI 的安装无法识别我的 PKG_CONFIG_PATH
- python-3.x - 在 Spark Pipeline 中部署 TensorFlow/Keras 模型
- matlab - 了解KNN的标准化过程
- c# - 如何在 c# windows 窗体中使用 n 层架构用数据库值填充组合框
- jquery - 单击角度链接后添加/删除类
- git - RTC(理性团队音乐会)中的进出是什么意思?
- java - 我的应用程序跳过启动意图并执行下一行代码?
- typescript - 检测 Word 上的更改(API Office)