是否可以使用触发触发器的行中的数据作为 pg_notify 的 channel ,如下所示:
CREATE OR REPLACE FUNCTION notify_pricesinserted()
RETURNS trigger AS $$
DECLARE
BEGIN
PERFORM pg_notify(
NEW.my_label,
row_to_json(NEW)::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER notify_pricesinserted
AFTER INSERT ON prices
FOR EACH ROW
EXECUTE PROCEDURE notify_pricesinserted();
编辑:我发现它不起作用的原因是我的标签的情况。如果我将它替换为 lower(NEW.my_label) 并且对监听器也执行相同的操作,那么它就可以工作了。
最佳答案
pg_notify()
部分可以正常工作而不会抛出错误。 PostgreSQL 对 channel 名称的限制很少。但实际上它可能没有用,因为您需要在 pg_notify()
语句之前建立一个 LISTEN some_channel
命令,以在触发函数之外的某处获取有效负载消息在大多数情况下,在某些动态值上这样做是很困难的,而且在所有情况下都可能非常低效。
如果 - 在您的触发器中 - NEW.my_label
具有少量明确定义的值,那么您可以通过在所有可能的值上建立监听 channel 来解决它,但您可能会更好为您的表或可能为这个特定的触发器定义一个单一的 channel 标识符,然后以这样一种方式构建有效负载消息,您可以轻松地为某些响应提取适当的信息。如果您无法预测 NEW.my_label
的值,那么这显然是不可能的。
在您的特定情况下,您可以使用 channel 名称“价格”,然后执行以下操作:
pg_notify('prices', format('%s: %s, NEW.my_label, row_to_json(NEW)::text));
LISTEN prices
session 将收到:
Asynchronous notification "prices" with payload "some_label: {new_row_to_json}" received from server process with PID 8448.
这是一个相当愚蠢的响应(为什么“异步通知“ channel ”与负载......”而不只是负载和 PID?)但您可以轻松提取相关部分并使用它们。由于无论如何您都必须操纵字符串,因此在单个 channel 上一次性去除所有 PG 开销并不是什么大负担,从而使触发操作的管理更加容易。
关于postgresql - 使用 pg_notify 触发器中的行数据作为 channel 名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31768976/