【问题标题】:LISTEN/NOTIFY using pg_notify(text, text) in PostgreSQL在 PostgreSQL 中使用 pg_notify(text, text) 监听/通知
【发布时间】:2011-07-07 14:19:15
【问题描述】:

我一直在使用 PostgreSQL 的通知系统,但我终其一生都无法弄清楚为什么 pg_notify(text, text) 永远不起作用。这个特性没有过多的记录,我找不到很多在野外使用它的例子,所以我想没有人会介意我在这里问。

完全按照预期运行以下内容:

LISTEN my_channel;

NOTIFY my_channel, 'my message text';

然而,使用 pg_notify() 函数会返回一个空值,并且不会发送任何通知。也没有给出错误。使用示例如下:

SELECT pg_notify('my_channel', 'my message text');

我可以使用 NOTIFY 函数,但我的目标是将通知简化为如下查询:

select pg_notify(get_player_error_channel(username)::TEXT, 'test'::TEXT)
    from player;

我想我一定错过了一些荒谬的东西,但我没有运气找出原因。可以在这里找到讨论 NOTIFY 的页面:http://www.postgresql.org/docs/9.0/static/sql-notify.html

在上面,它提到了关于 pg_notify() 的内容,这让我认为不会有太大的不同。

pg_notify 要发送通知,您还可以使用函数 pg_notify(text, text)。该函数将通道名称作为第一个参数,将有效负载作为第二个参数。如果您需要使用非常量的通道名称和有效负载,该函数比 NOTIFY 命令更易于使用。

一如既往地感谢您的帮助

编辑:数据库版本是: "PostgreSQL 9.0.3 on i686-pc-linux-gnu,由 GCC gcc (GCC) 4.2.4 编译,32 位"

【问题讨论】:

  • 您使用的是哪个 postgresql 版本?选择版本()!
  • 在 psql 会话中输入LISTEN my_channel; SELECT pg_notify('my_channel', 'my message text'); 不会输出任何内容吗?对我来说,pg_notify 的结果伴随着“异步通知...”消息。
  • 感谢 araqnid,这有助于向我保证我不会发疯!不幸的是,这也让我看起来有点愚蠢。哦,好吧。我的答案如下。
  • 别心疼Abstrct,您给出的答案确实突出了对解析器工作方式的理解,而这一点并不多见。哎呀,对我来说有些新东西,也会为我解释一些非触发通知,所以答案很好。 :)

标签: database notifications postgresql


【解决方案1】:

我已经在 PostgreSQL 邮件列表 (http://archives.postgresql.org/pgsql-bugs/2011-03/msg00041.php) 上讨论了这个问题,并被告知了这种行为的原因。

他们的回答是“..你必须双引号 relnames(听“测试”)。如果你 希望服务器不要折叠它们。 pg_notify 接受一个字符串,而不是一个 relname,它使用不同的规则。”(感谢 Merlin 和 Tom)

这意味着以下内容有效,因为通道总是强制小写

LISTEN ERRORCHANNEL;

NOTIFY ERRORCHANNEL, 'something!';
NOTIFY eRrorChanNel, 'something!';

如果您要在频道名称周围添加双引号,则将保留大小写。

因此,使用以下内容,您将收到第一个通知,但不会收到第二个通知:

LISTEN "ERRORCHANNEL";

NOTIFY "ERRORCHANNEL", 'something!'; 
NOTIFY "eRrorChanNel", 'something!';

同样,由于双引号会强制保持 ERRORCHANNEL 的大小写,因此以下操作也可以:

LISTEN "ERRORCHANNEL";

SELECT pg_notify('ERRORCHANNEL', 'something!');

虽然这不起作用:

LISTEN ERRORCHANNEL;

SELECT pg_notify('ERRORCHANNEL', 'something!');

在这种情况下,LISTEN 命令中的 ERRORCHANNEL 不在双引号中,因此 PostgreSQL 将其强制为小写。 channel 参数的类型是 text 而不是 relname,因此 pg_notify() 函数中的大小写保持不变。频道一起不匹配 (ERRORCHANNE != errorchannel),因此永远不会收到通知。

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 1970-01-01
    • 2015-10-01
    • 2018-05-14
    • 2022-12-01
    • 2023-02-13
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多