2011-02-05 5 views
5

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

CREATE OR REPLACE FUNCTION f_IsValidEmail(text) returns BOOLEAN AS 
'select $1 ~ ''^[^@\s][email protected][^@\s]+(\.[^@\s]+)+$'' as result 
' LANGUAGE sql; 



SELECT f_IsValidEmail('[email protected]'); 

Функция возвращает false, что должно быть правдой. Я пробовал пару других регулярных выражений, но напрасно. Может ли кто-нибудь указать, что не так с этой функцией?

Screenshot

+0

И ваша проблема? Я не вижу ограничений в вашем коде –

+0

Чтобы быть более конкретным, я опубликовал только функцию, которая не работает. –

+0

А что именно «не работает»? Вы получили сообщение об ошибке? Как выглядит ограничение проверки? –

ответ

7

Прежде, чем вы приложите много усилий к этому, вы должны сделать то, что вы не выкидываете действительные адреса электронной почты. Существуют всевозможные сумасшедшие правила, которые могут или не могут быть в адресе электронной почты, и если вы ошибетесь, в неправильном направлении, пользователь с вполне допустимым адресом электронной почты может быть отклонен вашей системой.

Лучший способ определить, является ли адрес электронной почты действительным, - использовать его как часть процесса регистрации, в котором ТРЕБУЕТСЯ электронная почта. Все остальное - это большая работа для небольшого выигрыша.

+3

Я не согласен с этим ответом. Жесткая проверка адреса электронной почты является самой всеобъемлющий метод проверки подлинности электронной почты, а также наименее практичный. То, что вы хотите, - это пользовательский домен Postgres, который не исключает один действительный адрес электронной почты. Затем вы хотите проверить только те, которые проходят очень низкую полосу пропускания. вы отбрасываете немедленный мусор и запрашиваете у пользователя разъяснения, никогда не бомбардируя ваш почтовый сервер явным нежеланием. Демонстрация: http://stackoverflow.com/a/22671557/ 124486 –

+0

Мех. Я вижу вашу точку зрения, но я думаю, что вам намного лучше убедиться, что у вас есть какая-то форма контроля над курсом, чтобы кто-то не наводнял вас реальными или фальшивыми адресами. После этого, если вы бросаете мусор на сервер электронной почты, это не имеет большого значения, потому что несколько неправильных адресов электронной почты в час просто не стоят того, чтобы беспокоиться об установке и установке plperlu на моих ящиках. –

0

работает для меня:

 
psql (9.0.2) 
Type "help" for help. 

postgres=> CREATE OR REPLACE FUNCTION "f_IsValidEmail"(text) returns BOOLEAN AS 
postgres-> 'select $1 ~ ''^[^@\s][email protected][^@\s]+(\.[^@\s]+)+$'' as result 
postgres'> ' LANGUAGE sql; 
CREATE FUNCTION 
postgres=> commit; 
COMMIT 
postgres=> SELECT "f_IsValidEmail"('[email protected]'); 
f_IsValidEmail 
---------------- 
t 
(1 row) 

postgres=> 
+0

Это не работает для меня. Я использую скрипт на pgAdmin III в новом окне запроса. –

+0

Работает для меня также в pgAdmin. Вы пытались psql? –

+0

I загрузили скриншот нового запроса pgAdmin. Не могли бы вы посмотреть и посмотреть, есть ли что-то не так? –

2

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

Для некоторых подводных камней см. regular-expressions.info.

+0

Домен - хорошая идея приготовить торт! –

3

Я рекомендую решение с использованием PL/Perl и модуля электронной почты :: Адрес. Что-то вроде следующего:

CREATE OR REPLACE FUNCTION email_valid(email text) RETURNS bool 
LANGUAGE plperlu 
AS $$ 
use Email::Address; 
my @addresses = Email::Address->parse($_[0]); 
return scalar(@addresses) > 0 ? 1 : 0; 
$$; 

См. Также http://wiki.postgresql.org/wiki/Email_address_parsing.

+0

Знаете ли вы что-то о производительности функций perl vs. plpgsql или sql? Учитывая требование, чтобы только регулярное выражение соответствовало значению. – Daniel

+0

Вы можете легко протестировать это самостоятельно, используя свои данные и выбранные вами реализации. –

+0

Благодарим вас за помощь Петра, но у меня нет перла. Можете ли вы, ребята, найти, что не так в функции. –

1

Не пытайтесь создать регулярное выражение для проверки электронной почты!

Это, как известно, трудно выполнить. Вот лучшее решение:

Если предположить, что у вас есть Perl, установленных на вашем сервере базы данных, установить E-mail :: Действительный модуль на одном хосте с помощью CPAN:

[email protected]$ cpan Email::Valid 

Затем убедитесь, что у вас есть PL/Perl установлен. Подключение к базе данных в PSQL и добавить plperlu как язык:

CREATE EXTENSION plperlu; 

(Имейте в виду, что это ненадежный язык, так что вы будете давая вашей БД прямого доступа к файлам, которые могут представлять угрозу безопасности, если . кто-то вставить вредоносный код в свои модули Perl или в функции дб Однако, вы должны сделать это для следующего шага)

Добавьте следующую функцию в базе данных:.

CREATE FUNCTION validate_email() RETURNS trigger AS $$ 
    use Email::Valid; 
    return if Email::Valid->address($_TD->{new}{email}); 
    elog(ERROR, "invalid email address $_TD->{new}{email} inserted into $_TD->{table_name}(email)"); 
    return "SKIP"; 
$$ LANGUAGE plperlu; 

Добавить триггер-ограничение для вашей таблицы в столбце (при условии, что вы r стол называется «пользователями», а ваша колонка называется «электронная почта»):

CREATE TRIGGER users_valid_email_trig 
    BEFORE INSERT OR UPDATE ON users 
    FOR EACH ROW EXECUTE PROCEDURE validate_email(); 

И все готово!

Это решение использует модуль Email: Valid Perl для обработки валидации, который, в свою очередь, полагается на регулярное выражение для обеспечения соответствия RFC 822. Тем не менее, это монстр регулярных выражений, поэтому не пытайтесь придумать свои собственные.

Если вы чувствуете дискомфорт при включении plperlu вместо обычного plperl, возможно, вы можете перенести соответствующие функции в свою базу данных.

+0

Это совсем не хорошая идея.Не используйте триггеры, использующие домен. –

+0

Мое предложение: http://stackoverflow.com/a/22671557/124486 –

+0

Почему триггеры совсем не хорошая идея? – earksiinni

10

Буква этих ответов закрыть на правильном пути. Это пункты моего представления.

  • Вы хотите использовать домен - НЕ СИСТЕМА правил.
  • Вы НЕ хотите проверять эти адреса электронной почты с помощью регулярного выражения. (Обновление от 2017 года: не совсем так)

Я покажу two methods of how to do this the right on DBA.StackExchange.com. И проверить MX-запись, а также использовать спецификацию HTML5. Вот короткое и сладкое.

CREATE EXTENSION citext; 
CREATE DOMAIN email AS citext 
    CHECK (value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'); 

SELECT '[email protected]'::email; 
SELECT CAST('[email protected]' AS email); 

Для получения дополнительной информации, которую я высоко предложить вам read the answer in full. В ответе Я также покажу, как вы создаете DOMAIN за Email::Valid и объясните, почему я больше не использую этот метод.

+0

Remeber, чтобы создавать функции на ненадежном языке, вам нужно быть суперпользователем postgresql. – Neoecos

Смежные вопросы