2011-02-05 13 views
5

Un vincolo di controllo che chiamerebbe una funzione per convalidare gli indirizzi e-mail non funziona correttamente per me.Funzione Postgres per convalidare l'indirizzo e-mail

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]'); 

La funzione restituisce false, che dovrebbe essere true. Ho provato un paio di altre regex ma invano. Qualcuno può segnalare cosa c'è di sbagliato in questa funzione?

Screenshot

+0

E il tuo problema è? Non vedo alcun vincolo di controllo nel codice –

+0

Per essere più specifico, ho pubblicato solo la funzione che non funziona. –

+0

E che cosa "non funziona" esattamente? Hai un errore? Come appare il vincolo del controllo? –

risposta

7

Prima di dedicarti a questo, la cosa che vuoi fare è assicurarti di non eliminare indirizzi email validi. Esistono tutti i tipi di regole folli che possono o non possono essere contenute in un indirizzo e-mail e, in caso di errore, nella direzione sbagliata, un utente con un indirizzo email perfettamente valido potrebbe essere rifiutato dal sistema.

Il modo migliore per determinare se un indirizzo e-mail è valido è quello di utilizzarlo come parte di un processo di registrazione in cui l'e-mail è OBBLIGATORIO. Qualsiasi altra cosa è molto lavoro per poco guadagno.

+3

Non sono d'accordo con questa risposta. metodo completo di convalida della posta elettronica e anche il meno pratico.Ciò che si desidera è un dominio Postgres personalizzato che non escluda un singolo indirizzo email valido. Quindi si desidera convalidare solo quelli che superano quella barra molto bassa. devi eliminare la spazzatura immediata e richiedere chiarimenti all'utente senza mai bombardare il tuo server di posta con evidente spazzatura. Dimostrazione: http://stackoverflow.com/a/22671557/ 124486 –

+0

Meh. Vedo il tuo punto di vista, ma penso che tu stia molto meglio assicurandoti di avere una qualche forma di controllo dei tassi in atto per impedire a qualcuno di allagarti con veri e propri indirizzi falsi. Dopodiché, il fatto che tu stia o meno buttando la posta indesiderata sul server di posta non è un grosso problema, perché pochi indirizzi email errati per un'ora non valgono la pena di preoccuparsi di E installare plperlu sulle mie scatole. –

0

funziona per me:

 
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

Questo non funziona per me. Sto usando lo script su pgAdmin III su una nuova finestra di query. –

+0

Funziona anche per me in pgAdmin. Hai provato psql? –

+0

I ho caricato uno screenshot di pgAdmin nuova query. Potresti dare un'occhiata e vedere se c'è qualcosa di sbagliato in questo? –

2

Se si riesce a capire un'espressione regolare che corrisponde indirizzi e-mail per la vostra soddisfazione, considerare se potrebbe non essere più utile come un dominio piuttosto che un controlla il vincolo.

Per alcune delle insidie, vedere regular-expressions.info.

+0

Il dominio è un'idea migliore per cucinare la torta! –

3

Raccomando una soluzione utilizzando PL/Perl e il modulo Email :: Indirizzo. Qualcosa come il seguente:

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; 
$$; 

Vedere anche http://wiki.postgresql.org/wiki/Email_address_parsing.

+0

Sai qualcosa sulle prestazioni di perl rispetto alle funzioni plpgsql vs sql? Dato il requisito che solo una regex dovrebbe essere confrontata con il valore. – Daniel

+0

Puoi facilmente testare te stesso usando i tuoi dati particolari e le implementazioni che hai scelto. –

+0

Grazie per l'aiuto Peter, ma non ho perl. Ragazzi, potete trovare cosa c'è che non va nella funzione. –

1

Non tentare di creare un'espressione regolare per convalidare le e-mail!

È notoriamente difficile da realizzare. Ecco una soluzione migliore:

Supponendo di avere Perl installato sul vostro host del database, installare il modulo E-mail :: Valido sullo stesso host utilizzando CPAN:

[email protected]$ cpan Email::Valid 

quindi assicurarsi che si dispone di PL/Perl installato. La connessione al database in psql e aggiungere plperlu come lingua:

CREATE EXTENSION plperlu; 

(Tenete a mente che questo è un linguaggio non attendibile, in modo darete il vostro accesso diretto ai file db, che potrebbe rappresentare un rischio per la sicurezza, se . qualcuno dovesse inserire codice dannoso nei vostri moduli Perl o nelle funzioni db Tuttavia, è necessario farlo per il passo successivo)

Aggiungere la seguente funzione al database:.

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; 

Aggiungi un innescare il vincolo alla tua tabella sulla tua colonna (supponendo che tu la tabella è denominata "utenti" e la colonna è denominata "email"):

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

E il gioco è fatto!

Questa soluzione utilizza il modulo Email :: Valid Perl per gestire la convalida, che a sua volta si basa su un'espressione regolare per garantire la conformità RFC 822. Tuttavia, è un mostro di una regex, quindi non provare a inventare il tuo.

Se ti senti a disagio nell'abilitare plperlu invece di plperl semplice, potresti probabilmente trasferire le funzioni rilevanti nel tuo database.

+0

Questa non è affatto una buona idea.Non usare i trigger usa un dominio. –

+0

Il mio suggerimento: http://stackoverflow.com/a/22671557/124486 –

+0

Perché i trigger non sono affatto una buona idea? – earksiinni

10

Un gruppo di queste risposte è vicino nel modo giusto. Questi sono i punti per la mia presentazione.

  • Si desidera utilizzare un dominio - NON il sistema di regole.
  • Si NON si desidera convalidare questi indirizzi di posta elettronica con un'espressione regolare. (Aggiornamento marzo 2017: non più proprio vero)

I show two methods of how to do this the right on DBA.StackExchange.com. Sia per controllare il record MX, sia per utilizzare le specifiche HTML5. Ecco il breve e dolce.

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); 

Per ulteriori informazioni ho altamente vi proponiamo read the answer in full. Nella risposta, , mostro anche come si crea un DOMAIN su Email::Valid e si spiega perché non utilizzo più tale metodo.

+0

Ricordare, per creare funzioni su un linguaggio non attendibile è necessario essere superutente postgresql. – Neoecos

Problemi correlati