在PostgreSQL中使用pg_notify(text,text)进行LISTEN / NOTIFY

时间:2011-03-02 20:54:54

标签: database notifications postgresql

我一直在玩PostgreSQL的通知系统,并且在我的生活中无法解释为什么pg_notify(文本,文本)永远不会起作用。这个功能没有过多记录,我找不到很多在野外使用的例子,所以我想没有人会介意我在这里问。

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

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命令更容易使用。

一如既往地感谢您的帮助

编辑:数据库版本是: “i6486-pc-linux-gnu上的PostgreSQL 9.0.3,由GCC gcc(GCC)4.2.4编译,32位”

1 个答案:

答案 0 :(得分:25)

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

他们的回答是“你必须加倍引用重新命名(听”测试“)。如果你 希望服务器不要折叠它们。 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!');

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