LISTEN/NOTIFY, используя pg_notify (текст, текст) в 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 (текст, текст). Функция принимает имя канала в качестве первого аргумента и полезную нагрузку как вторую. Функция намного проще в использовании, чем команда NOTIFY, если вам нужно работать с непостоянными названиями каналов и полезными нагрузками.
Спасибо, как всегда за помощь
Изменить: версия базы данных:
"PostgreSQL 9.0.3 на i686-pc-linux-gnu, скомпилированный GCC gcc (GCC) 4.2.4, 32-разрядный"
Ответы
Ответ 1
Я обсуждал это в списке рассылки 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 заставляет ее ограничивать регистр. Параметр канала имеет тип текста, а не relname, поэтому случай не затрагивается функцией pg_notify(). Вместе каналы не совпадают (ERRORCHANNE!= Errorchannel), поэтому уведомление никогда не принимается.
Ответ 2
Если вы делаете это из своего приложения, вам необходимо активно опросить базу данных для новых уведомлений.
Отсутствует "push" от сервера к клиенту.
В JDBC вам нужно запустить какой-то оператор SELECT, а затем все ожидающие уведомления будут доступны в объекте Connection (см. http://jdbc.postgresql.org/documentation/head/listennotify.html)
Я не знаю, как это работает для других языков программирования. Я думаю, что libpq (C/С++) имеет специальные функции для прямого извлечения уведомлений без запуска select