2008-10-23 27 views
25

Ok, hay un millón de expresiones regulares para validar una dirección de correo electrónico, pero ¿qué tal una validación de correo electrónico básica que se puede integrar en una consulta TSQL para SQL Server 2005?Validación de correo electrónico TSQL (sin regex)

No deseo utilizar un procedimiento o función CLR. Justo derecho TSQL.

¿Alguien ha abordado esto ya?

+0

posible duplicado de [secuencia de comandos SQL para encontrar direcciones de correo electrónico no válidas] (http://stackoverflow.com/questions/801166/sql-script- to-find-invalid-email-addresses) – Neolisk

Respuesta

42

Muy básica sería:

SELECT 
    EmailAddress, 
    CASE WHEN EmailAddress LIKE '%[email protected]_%_.__%' 
      AND EmailAddress NOT LIKE '%[any obviously invalid characters]%' 
    THEN 'Could be' 
    ELSE 'Nope' 
    END Validates 
FROM 
    Table 

Esto coincide con todo con un @ en el medio, precedido por al menos un carácter, seguido por al menos dos, un punto y, al menos, dos para el TLD .

Puede escribir más patrones LIKE que hacen cosas más específicas, pero nunca podrá hacer coincidir todo lo que podría ser una dirección de correo electrónico sin dejar escapar las cosas que no lo son. Incluso con expresiones regulares, es difícil hacerlo bien. Además, incluso el emparejamiento de acuerdo con las mismas letras del RFC coincide con los constructos de direcciones que no serán aceptados/usados ​​por la mayoría de los sistemas de envío de correos electrónicos.

Hacer esto en el nivel de base de datos es tal vez el enfoque incorrecto, por lo que un control de cordura básico como se indicó anteriormente puede ser lo mejor que se puede obtener en cuanto a rendimiento, y hacerlo en una aplicación le proporcionará mucha más flexibilidad.

+0

Sí, ya tengo expresiones regulares en el código que hacen esto por mí, pero tengo que informar sobre tablas con tropecientos correos electrónicos y crear agregados. –

+0

Conociendo los datos básicos que tiene, es posible que pueda encontrar algo más específico y apropiado de lo que sugerí para comenzar, pero nunca lo obtendrá "correcto" ya que la palabra se usa en la teoría de algoritmos. – Tomalak

+0

Veo que agregó "no me gusta"% [cualquier carácter obviamente inválido]% ".Por lo que he aprendido sobre la especificación, no estoy seguro de que existan en realidad teclas en el teclado que técnicamente no se puedan interpretar como válidas en algún lugar de la dirección. –

18

Aquí es una función de ejemplo de este que es un poco más detallada, no me acuerdo donde me dieron esto desde (hace años), o si lo modifico, de lo contrario me gustaría incluir la atribución apropiada:

CREATE FUNCTION [dbo].[fnAppEmailCheck](@email VARCHAR(255)) 
--Returns true if the string is a valid email address. 
RETURNS bit 
as 
BEGIN 
    DECLARE @valid bit 
    IF @email IS NOT NULL 
      SET @email = LOWER(@email) 
      SET @valid = 0 
      IF @email like '[a-z,0-9,_,-]%@[a-z,0-9,_,-]%.[a-z][a-z]%' 
      AND LEN(@email) = LEN(dbo.fnAppStripNonEmail(@email)) 
      AND @email NOT like '%@%@%' 
      AND CHARINDEX('[email protected]',@email) = 0 
      AND CHARINDEX('..',@email) = 0 
      AND CHARINDEX(',',@email) = 0 
      AND RIGHT(@email,1) between 'a' AND 'z' 
       SET @valid=1 
    RETURN @valid 
END 
+5

Hola, cabgef, esta es la mejor solución que te dan . ¿Podría decirme qué hace "fnAppStripNonEmail"? –

+3

Necesitaba agregar una condición 'Y CHARINDEX ('', @ email) = 0' para verificar espacios en medio de la dirección de correo electrónico. –

+0

Sé que esta es una publicación anterior, pero para otros usuarios se benefician - Esto arroja un error: "Máximo procedimiento almacenado, función, desencadenante o nivel de anidación de la vista excedido (límite 32)" – user1948635

-2

de slelect de Tomalak

select 1 
where @email not like '%[^a-z,0-9,@,.]%' 
and @email like '%[email protected]_%_.__%' 
0
Create Function [dbo].[fnAppStripNonEmail](@Temp VarChar(1000)) 
Returns VarChar(1000) 
AS 
Begin 

    Declare @KeepValues as varchar(50) 
    Set @KeepValues = '%[^a-z,0-9,@,.,-]%' 
    While PatIndex(@KeepValues, @Temp) > 0 
     Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '') 

    Return @Temp 
End 
0

Esta es la forma más fácil para seleccionarlos.

utilizar esta consulta

SELECT * FROM <TableName> WHERE [EMail] NOT LIKE '%[email protected]__%.__%' 
0

FnAppStripNonEmail falta bajo puntaje, necesitará añadir al mantener los valores

Create Function [dbo].[fnAppStripNonEmail](@Temp VarChar(1000)) 
Returns VarChar(1000) 
AS 
Begin 

    Declare @KeepValues as varchar(50) 
    Set @KeepValues = '%[^a-z,0-9,_,@,.,-]%' 
    While PatIndex(@KeepValues, @Temp) > 0 
     Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '') 

    Return @Temp 
End 
3

Grandes respuestas! Basado en estas recomendaciones, se me ocurrió una función simplificada que combina las mejores 2 respuestas.

CREATE FUNCTION [dbo].[fnIsValidEmail] 
(
    @email varchar(255) 
) 
--Returns true if the string is a valid email address. 
RETURNS bit 
As 
BEGIN 
    RETURN CASE WHEN ISNULL(@email, '') <> '' AND @email LIKE '%[email protected]%_.__%' THEN 1 ELSE 0 END 
END 
0
CREATE FUNCTION fnIsValidEmail 
(
    @email varchar(255) 
) 
RETURNS bit 
AS 
BEGIN 

    DECLARE @IsValidEmail bit = 0 

    IF (@email not like '%[^a-z,0-9,@,.,!,#,$,%%,&,'',*,+,--,/,=,?,^,_,`,{,|,},~]%' --First Carat^means Not these characters in the LIKE clause. The list is the valid email characters. 
     AND @email like '%[email protected]_%_.[a-z,0-9][a-z]%' 
     AND @email NOT like '%@%@%' 
     AND @email NOT like '%..%' 
     AND @email NOT like '.%' 
     AND @email NOT like '%.' 
     AND CHARINDEX('@', @email) <= 65 
     ) 
    BEGIN 
     SET @IsValidEmail = 1 
    END 

    RETURN @IsValidEmail 

END 
0

En SQL 2016 o +

CREATE FUNCTION [DBO].[F_IsEmail] (
@EmailAddr varchar(360) -- Email address to check 
) RETURNS BIT -- 1 if @EmailAddr is a valid email address 

AS BEGIN 
DECLARE @AlphabetPlus VARCHAR(255) 
     , @Max INT -- Length of the address 
     , @Pos INT -- Position in @EmailAddr 
     , @OK BIT -- Is @EmailAddr OK 
-- Check basic conditions 
IF @EmailAddr IS NULL 
    OR @EmailAddr NOT LIKE '[0-9a-zA-Z]%@__%.__%' 
    OR @EmailAddr LIKE '%@%@%' 
    OR @EmailAddr LIKE '%..%' 
    OR @EmailAddr LIKE '%[email protected]' 
    OR @EmailAddr LIKE '%@.' 
    OR @EmailAddr LIKE '%@%.-%' 
    OR @EmailAddr LIKE '%@%-.%' 
    OR @EmailAddr LIKE '%@-%' 
    OR CHARINDEX(' ',LTRIM(RTRIM(@EmailAddr))) > 0 
     RETURN(0) 



declare @AfterLastDot varchar(360); 
declare @AfterArobase varchar(360); 
declare @BeforeArobase varchar(360); 
declare @HasDomainTooLong bit=0; 

--Control des longueurs et autres incoherence 
set @AfterLastDot=REVERSE(SUBSTRING(REVERSE(@EmailAddr),0,CHARINDEX('.',REVERSE(@EmailAddr)))); 
if len(@AfterLastDot) not between 2 and 17 
RETURN(0); 

set @AfterArobase=REVERSE(SUBSTRING(REVERSE(@EmailAddr),0,CHARINDEX('@',REVERSE(@EmailAddr)))); 
if len(@AfterArobase) not between 2 and 255 
RETURN(0); 

select top 1 @BeforeArobase=value from string_split(@EmailAddr, '@'); 
if len(@AfterArobase) not between 2 and 255 
RETURN(0); 

--Controle sous-domain pas plus grand que 63 
select top 1 @HasDomainTooLong=1 from string_split(@AfterArobase, '.') where LEN(value)>63 
if @HasDomainTooLong=1 
return(0); 

--Control de la partie locale en detail 
SELECT @AlphabetPlus = 'abcdefghijklmnopqrstuvwxyz!#$%&‘*+-/=?^_`.{|}~' 
    , @Max = LEN(@BeforeArobase) 
    , @Pos = 0 
    , @OK = 1 


WHILE @Pos < @Max AND @OK = 1 BEGIN 
    SET @Pos = @Pos + 1 
    IF @AlphabetPlus NOT LIKE '%' + SUBSTRING(@BeforeArobase, @Pos, 1) + '%' 
     SET @OK = 0 
END 

if @OK=0 
RETURN(0); 

--Control de la partie domaine en detail 
SELECT @AlphabetPlus = 'abcdefghijklmnopqrstuvwxyz-.' 
    , @Max = LEN(@AfterArobase) 
    , @Pos = 0 
    , @OK = 1 

WHILE @Pos < @Max AND @OK = 1 BEGIN 
    SET @Pos = @Pos + 1 
    IF @AlphabetPlus NOT LIKE '%' + SUBSTRING(@AfterArobase, @Pos, 1) + '%' 
     SET @OK = 0 
END 

if @OK=0 
RETURN(0); 







return(1); 



END 
Cuestiones relacionadas