2011-03-02 58 views
14

我一直在玩PostgreSQL的通知系統,不能爲我的數字生活爲什麼pg_notify(文本,文本)從來沒有工作。這個功能沒有過多的記錄,我找不到很多它在野外使用的例子,所以我想沒有人會介意我在這裏問。在PostgreSQL中使用pg_notify(文本,文本)的LISTEN/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(文本,文本)。該函數將通道名稱作爲第一個參數,將有效負載作爲第二個參數。如果您需要處理非常量通道名稱和有效載荷,該功能比NOTIFY命令更易於使用。

感謝一如既往爲輔助

編輯:數據庫的版本是:在i686-PC-Linux的GNU 「的PostgreSQL 9.0.3,GCC由海灣合作委員會(GCC)4.2.4編譯,32位「

+0

你正在使用哪個postgresql版本? SELECT版本()! – Daniel 2011-03-02 21:01:17

+0

輸入'LISTEN my_channel;''選擇pg_notify('my_channel','我的消息文本');'進入psql會話不輸出任何內容?它對我來說,pg_notify的結果伴隨着「Asynchronous notification ...」消息。 – araqnid 2011-03-02 21:33:05

+0

感謝araqnid,這有助於保證我不會發瘋!不幸的是,這也有助於讓我看起來很愚蠢。好吧。我的答案如下。 – Abstrct 2011-03-02 21:44:43

回答

21

我已經在PostgreSQL郵件列表上討論了這個問題(http://archives.postgresql.org/pgsql-bugs/2011- 03/msg00041.php)並被告知該行爲的推理。

他們的回答是,」 ..你有雙引號relnames(聽‘測試’)。如果你想 服務器不區分摺疊他們。pg_notify需要一個字符串,而不是一個 relname,它使用不同的規則。「(感謝梅林和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),所以通知永遠不會被接收到。

-1

如果您在應用程序內部執行此操作,則需要主動輪詢數據庫以獲取新通知。

沒有從服務器到客戶端的「推送」。

在JDBC,你需要運行某種SELECT語句,然後任何未決的通知將可在Connection對象上(見http://jdbc.postgresql.org/documentation/head/listennotify.html

我不知道這是如何工作的其他編程語言。我認爲libpq(C/C++)具有特殊功能,可以直接檢索通知而不需要運行select

+0

我有一個小的python腳本輪詢服務器的新通知。使用NOTIFY命令完美地工作。只有pg_notify(文本,文本)函數不起作用。 – Abstrct 2011-03-02 21:10:09

+17

*有*從服務器到客戶端的推送。這只是一些客戶端數據庫適配器不能異步處理此類通知。如果你將連接fd集成到你自己的'select()'循環或類似的環境中,libpq和psycopg2可以* *。 – intgr 2011-03-24 09:32:07