postgresql - 使用 pg_notify 触发器中的行数据作为 channel 名称?

标签 postgresql

是否可以使用触发触发器的行中的数据作为 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/

相关文章:

ruby-on-rails - Heroku pg 问题

postgresql - 如何在没有 FK 的情况下映射表

postgresql - 一张表只保留3条最高的正负记录

postgresql - 镜像 postgreSQL 中的特定表

java - Eclipse 插件中的 Postgres 驱动程序不断出现找不到类异常

postgresql - Postgres 使用 TypeORM SET 运行时变量,如何在调用之间的连接生命周期中保留变量

postgresql - 数据库连接自动关闭

sql-server - PostgreSQL 和 SQL Server b 树存储基础问题

macos - PG::ConnectionBad 升级到 Yosemite 和 postgresql 9.4.4

postgresql - 撤销 postgresql 中的特定列