是否有可能(如何?)从 "after update" 触发器到 return 旧值
Is it possible (how?) to return old value from "after update" trigger
UPDATE "Users"
SET "displayName" = 'new_name'
WHERE id = 1
RETURNING "displayName"
查询以上 returns NEW 值。
我想知道 OLD 更新后 displayName
的值。我知道可以:
UPDATE ...
FROM SELECT ...
RETURNING ...
但我想使用 AFTER UPDATE
触发器。是否有可能 "return" 来自 AFTER UPDATE
的旧值以某种方式触发?如果是的话,这样的扳机体会是什么样子?
是的,但是这里根本不涉及触发器。只是一个普通的 UPDATE
.
RETURNING
子句 returns 值基于行 在 更新后。但是您可以将旧行包含在 FROM
子句中并使用 that。 Per documentation:
Any expression using the table's columns, and/or columns of other tables mentioned in FROM
, can be computed. The new (post-update) values of the table's columns are used.
解决方案:
UPDATE "Users" x
SET "displayName" = 'new_name'
FROM (SELECT id, "displayName" FROM "Users" WHERE id = 1 FOR UPDATE) y
WHERE x.id = y.id
RETURNING y."displayName"
详细解释:
- Return pre-UPDATE Column Values Using SQL Only - PostgreSQL Version
如果我的 ORM 不允许 FROM
子句怎么办?
你确定吗?如果是这样,一个简单(更昂贵)的替代方法是 运行 两个语句:
BEGIN;
-- Retrieve old value first;
SELECT "displayName" FROM "Users" WHERE id = 1 FOR UPDATE;
UPDATE "Users"
SET "displayName" = 'new_name'
WHERE id = 1;
COMMIT;
事务包装器 (BEGIN; ... COMMIT;
) 和行上的锁 (FOR UPDATE
) 是为了防止可能的并发写入。如果你是唯一一个写入 table 的人,或者如果偶尔有过时的“旧值”是可以的,你可以删除两者。除非在非常有竞争力的设置中,否则很少发生。
或者使用原始 SQL 绕过劣质 ORM。
我可以想象解决这个问题的技巧(比如添加一个更新前值为 "displayName"
的冗余列),但这种技巧听起来 非常糟糕的主意.只需使用标准功能即可。
UPDATE "Users"
SET "displayName" = 'new_name'
WHERE id = 1
RETURNING "displayName"
查询以上 returns NEW 值。
我想知道 OLD 更新后 displayName
的值。我知道可以:
UPDATE ...
FROM SELECT ...
RETURNING ...
但我想使用 AFTER UPDATE
触发器。是否有可能 "return" 来自 AFTER UPDATE
的旧值以某种方式触发?如果是的话,这样的扳机体会是什么样子?
是的,但是这里根本不涉及触发器。只是一个普通的 UPDATE
.
RETURNING
子句 returns 值基于行 在 更新后。但是您可以将旧行包含在 FROM
子句中并使用 that。 Per documentation:
Any expression using the table's columns, and/or columns of other tables mentioned in
FROM
, can be computed. The new (post-update) values of the table's columns are used.
解决方案:
UPDATE "Users" x
SET "displayName" = 'new_name'
FROM (SELECT id, "displayName" FROM "Users" WHERE id = 1 FOR UPDATE) y
WHERE x.id = y.id
RETURNING y."displayName"
详细解释:
- Return pre-UPDATE Column Values Using SQL Only - PostgreSQL Version
如果我的 ORM 不允许 FROM
子句怎么办?
你确定吗?如果是这样,一个简单(更昂贵)的替代方法是 运行 两个语句:
BEGIN;
-- Retrieve old value first;
SELECT "displayName" FROM "Users" WHERE id = 1 FOR UPDATE;
UPDATE "Users"
SET "displayName" = 'new_name'
WHERE id = 1;
COMMIT;
事务包装器 (BEGIN; ... COMMIT;
) 和行上的锁 (FOR UPDATE
) 是为了防止可能的并发写入。如果你是唯一一个写入 table 的人,或者如果偶尔有过时的“旧值”是可以的,你可以删除两者。除非在非常有竞争力的设置中,否则很少发生。
或者使用原始 SQL 绕过劣质 ORM。
我可以想象解决这个问题的技巧(比如添加一个更新前值为 "displayName"
的冗余列),但这种技巧听起来 非常糟糕的主意.只需使用标准功能即可。