postgresql - 如果 NEW 等于 OLD 而没有触发器,则 Postgres 跳过更新
问题描述
假设我有一个表,我需要使用新的、更改的和未更改的现有数据的混合来更新(由于遗留原因,我们不能将它们分成 3 个不同的调用)。
最小的示例表是这样的:
(
id integer,
name text
constraint name_unique
unique,
metadata jsonb,
version integer default 0
);
有 3 件不同的事情需要发生:
name
如果不存在则插入新值(INSERT ... ON CONFLICT (name) ...
)- 更新和
metadata
碰撞if已经存在并且<- 这是我不能用语法写下来的那个,因为它只有(?)让我可以访问value as而不是手头的值 in 。version
1
name
OLD.metadata <> NEW.metadata
ON CONFLICT
NEW
EXCLUDED
ROW
- 跳过更新和版本碰撞如果
OLD.metadata = NEW.metadata
我目前最好的猜测是转换jsonb
为纯文本,看看两者是否相同,但我不知道是否可以在不必编写 aFUNCTION
和 a 的情况下做到这一点TRIGGER
。
这三件事可以在一个查询中执行吗?
解决方案
EXCLUDED
您可以在ON CONFLICT ... DO UPDATE
子句中引用新的行版本:
INSERT INTO tab (name, metadata)
VALUES ('obadja', '{"silly": 42}')
ON CONFLICT ON name_unique
DO UPDATE SET metadata = EXCLUDED.metadata,
version = tab.version + 1
WHERE tab.metadata IS DISTINCT FROM EXCLUDED.metadata;
推荐阅读
- python - 有没有更快的方法从整个计算机中找到每张图像?
- r - 如何通过将相同的值写入同一行来将两个不同长度的向量写入一个数据帧?
- vba - 通过按钮打开重新链接对话框
- r - R - 将重复的行旋转为具有未知列数的多列
- javascript - Javascript:我可以返回对在我调用的函数之外定义的函数的引用吗?
- python - 如何应用 scikit-learn 已热编码的数据集来做决策树?
- php - 如何使用 github 操作部署 laravel 应用程序
- javascript - 我可以用一组控制器控制 2 个引导轮播吗?
- javascript - 如何使 .bindpopup 中的元素可用于传单中的外部函数?
- android - 如何在 Android 9 上集成系统应用