是否可以使用触发器触发的行中的数据作为pg_notify的通道,如下所示:
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();
编辑:我发现它不起作用的原因是由于我的标签。如果我用较低的(NEW.my_label)替换它,并且也为听众做同样的事情,那么它就可以了。
答案 0 :(得分:0)
pg_notify()
部分可以正常运行而不会出错。 PostgreSQL对频道名称的限制很少。但实际上它可能没用,因为您需要在LISTEN some_channel
语句之前建立pg_notify()
命令以在触发器函数之外的某处拾取有效负载消息,并且在某些动态值上执行此操作很困难在大多数情况下,在所有情况下都可能非常低效。
如果 - 在您的触发器中 - NEW.my_label
具有少量明确定义的值,那么您可以通过在所有可能的值上建立侦听通道来解决这个问题,但您最好定义单个通道标识符对于您的表,或者可能对于此特定触发器,然后构造有效负载消息,以便您可以轻松地为某些响应提取适当的信息。如果你无法预测NEW.my_label
的值,那么这根本不可能。
在您的具体情况下,您可以拥有频道名称'价格'然后做类似的事情:
pg_notify('prices', format('%s: %s, NEW.my_label, row_to_json(NEW)::text));
与LISTEN prices
的会话将收到:
Asynchronous notification "prices" with payload "some_label: {new_row_to_json}" received from server process with PID 8448.
这是一个相当愚蠢的回应(为什么"异步通知"频道"有效载荷..."而不仅仅是有效载荷和PID?)但你可以轻松提取相关部分并与之合作。因为你无论如何都必须操纵字符串,所以在一个通道上一次性去除所有PG开销并不是一个很大的负担,这使得触发操作的管理变得更加容易。