使用pg_notify触发器中的行数据作为通道名称?

时间:2015-08-02 05:49:47

标签: postgresql

是否可以使用触发器触发的行中的数据作为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)替换它,并且也为听众做同样的事情,那么它就可以了。

1 个答案:

答案 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开销并不是一个很大的负担,这使得触发操作的管理变得更加容易。

相关问题