Как я могу отправить электронное письмо из триггера PostgreSQL?

Я использую pgsql для установки триггера, когда обновляю набор данных таблицы (меняя статус на Готово), он автоматически отправляет электронное письмо на учетную запись электронной почты с использованием значения электронной почты набора данных и сохраняет это электронное письмо на сервере

но я не знаю, как написать в функции триггера для отправки электронной почты и отправки электронной почты на сервер. заранее спасибо

Версия Pg - 9.1, а CentOS 5.8.

CREATE OR REPLACE FUNCTION sss()
RETURNS trigger AS
$BODY$begin
if(NEW.publisher== 'aaaa')
then
//send email and save to server 192.168.171.64
end if;
return NEW;
end

$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sss()
OWNER TO postgres;
GRANT EXECUTE ON FUNCTION sss() TO postgres;

person AntiGMO    schedule 17.08.2012    source источник
comment
Задавая вопросы о Pg, действительно полезно немного рассказать о вашей настройке, в частности о вашей версии Pg. У разных версий разные функции, поэтому версия может повлиять на ответы.   -  person Craig Ringer    schedule 17.08.2012


Ответы (5)


См. отличную статью о depesz и pg-message-queue.

Отправка электронной почты непосредственно из базы данных может быть не самой лучшей идеей. Что делать, если разрешение DNS медленное и все зависает на 30 секунд, а затем истекает время ожидания? Что делать, если ваш почтовый сервер шатается и принимает сообщения 5 минут? Вы будете зависать от сеансов базы данных в своем триггере до тех пор, пока не достигнете max_connections, и внезапно вы ничего не сможете сделать, кроме как подождать или начать отмену транзакций вручную.

Я бы порекомендовал, чтобы ваш триггер NOTIFY LISTENing вспомогательный скрипт, который постоянно работает и подключен к БД (но не в транзакции).

Все, что нужно сделать вашему триггеру, - это INSERT создать строку в таблице очереди и отправить NOTIFY. Ваш сценарий получает сообщение NOTIFY, потому что он зарегистрировался для него в LISTEN, проверяет таблицу очереди и делает все остальное.

Вы можете написать вспомогательную программу на любом удобном языке; Обычно я использую Python с psycopg2.

Этот сценарий может отправлять электронную почту на основе информации, которую он находит в базе данных. Вам не нужно выполнять все уродливое форматирование текста в PL / PgSQL, вместо этого вы можете подставлять элементы в шаблон на более мощном языке сценариев и просто извлекать данные переменных из базы данных, когда приходит NOTIFY.

При таком подходе ваш помощник может отправлять каждое сообщение и только затем удалять информацию из таблицы очереди. Таким образом, если в вашей почтовой системе возникают временные проблемы, которые приводят к сбою отправки, вы не потеряли информацию и можете продолжать попытки отправить ее, пока не добьетесь успеха.

Если вам действительно необходимо сделать это в базе данных, см. PgMail.

person Craig Ringer    schedule 17.08.2012
comment
@JesseSiu Кажется, вы скопировали и вставили этот комментарий из другого комментария, который вы разместили час назад по другому ответу. Этот ответ не имеет ничего общего с PL / Perl, и я не рекомендую вам использовать его по причинам, изложенным в моем ответе. Используйте сценарий, работающий вне базы данных, для отправки почты. - person Craig Ringer; 20.08.2012
comment
@JesseSiu Если вы не поняли приведенный выше совет или он не сработает для вас, не стесняйтесь объяснять или просить разъяснений, я буду рад помочь. Я просто думаю, что вы ошибаетесь. - person Craig Ringer; 20.08.2012
comment
На самом деле я написал pg-message-queue специально, чтобы это был ответ на этот вопрос. - person Chris Travers; 29.12.2019

  1. Используйте локальный MTA (это дает вам централизованную конфигурацию SMTP для нескольких приложений)
  2. Установите локальный ретранслятор MTA на ваш настоящий MTA (по сути, это дает вам асинхронную поддержку)
  3. Если Windows, используйте клиент командной строки SMTP blat. Убедитесь, что путь к blat находится в PATH
  4. Вероятно, вам следует сделать это с помощью Apache Camel или pgAgent, а не напрямую в триггере.

Это будет работать в Windows, если postgres superuser. Функция триггера должна быть ОПРЕДЕЛЕНИЕМ БЕЗОПАСНОСТИ. Аналогично sendmail в Linux:

...

copy 
  ( select 'my email body' ) 
to program 
  'blat -to [email protected] -from [email protected] -subject "My Subject" -server localhost:25' 
with (
  format text
);

...

~ 60 ms

person Neil McGuigan    schedule 17.08.2014
comment
Это именно то решение, которое я искал, слишком плохое для программирования, оно доступно только с PostgreSQL 9.3. - person Thorsten Schöning; 08.04.2016

Вы можете использовать plperlu для отправки почты.

Эта ссылка показывает пример того, как использовать ее на курок.

person Diego    schedule 17.08.2012
comment
Спасибо, но язык - plpgsql, и когда я печатаю, используйте Mail :: Sendmail; показывает синтаксическую ошибку - person AntiGMO; 17.08.2012
comment
@JesseSiu Вы должны CREATE LANGUAGE plperlu; как суперпользователь, прежде чем сможете его использовать, и использовать LANGUAGE 'plperlu';. - person Craig Ringer; 17.08.2012
comment
когда я набираю createlang plperlu mydb. он сказал, что не удалось открыть файл управления расширением. в папке расширения он не содержит файла plperlu.control? Как я могу сделать - person AntiGMO; 20.08.2012
comment
@JesseSiu Это полностью зависит от того, как вы установили PostgreSQL. Вы все еще не обновили свой ответ, полученный два дня назад, когда я попросил вас добавить вашу версию Pg. Может быть, вам стоит сделать это и объяснить, на какой ОС вы работаете и как вы устанавливали Pg, пока вы на ней? Как только эта информация станет доступной, кто-нибудь сможет вам помочь. - person Craig Ringer; 20.08.2012
comment
извините, я забыл добавить информацию. Версия Pg - 9.1, а CentOS 5.8. - person AntiGMO; 20.08.2012
comment
привет, я использую ваш метод, но произошла ошибка Не могу найти Mail / Sendmail.pm в @INC (@INC содержит: / usr / .... вы видите эту ссылку stackoverflow.com/questions/12243335/ - person AntiGMO; 03.09.2012

У вас есть возможность использовать pgMail (если вам разрешено его установить):

Если вы следуете инструкциям на brandolabs.com, все сводится к

pgmail('Send From ','Send To ','Subject goes here','Message body here.')
person Eggi    schedule 17.08.2012
comment
могу ли я использовать другой способ без установки pgmail? - person AntiGMO; 17.08.2012
comment
Вы можете использовать это (с установкой программы) или использовать программу plperlu из поста ниже. - person Eggi; 17.08.2012

Я согласен с @Craig Ringer. Вы можете написать что-нибудь на Python до 100 строк кода. Я бы рекомендовал использовать следующие библиотеки Python: psycopg2, smtplib. В зависимости от того, как часто вы хотите получать уведомления об изменениях, вы можете запустить задание cron (в зависимости от вашей рабочей среды). Таким образом, вы можете объединить несколько изменений в базе данных в одно электронное письмо, а не отправлять уведомление каждый раз, когда происходит изменение.

person Adrian Aksan    schedule 05.02.2016