代码之家  ›  专栏  ›  技术社区  ›  Eric Z Beard

TSQL电子邮件验证(不带regex)

  •  30
  • Eric Z Beard  · 技术社区  · 16 年前

    好的,现在有一百万个regex用于验证电子邮件地址,但是对于可以集成到SQL Server 2005的TSQL查询中的一些基本电子邮件验证呢?

    我不想使用clr过程或函数。直接的TSQL。

    有人已经解决了这个问题吗?

    9 回复  |  直到 7 年前
        1
  •  48
  •   Tomalak    16 年前

    非常 基本是:

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

    这与中间的@匹配,前面至少有一个字符,后面至少有两个字符,一个点,TLD至少有两个字符。

    你可以写更多 LIKE 模式可以做更具体的事情,但是你永远无法匹配所有可能是电子邮件地址的东西,同时又不让那些没有的东西溜走。即使使用正则表达式,您也很难正确地执行它。此外,即使根据RFC的字母进行匹配,也会匹配大多数电子邮件系统不会接受/使用的地址构造。

    无论如何,在数据库级别执行此操作可能是错误的方法,因此如上所述的基本健全性检查可能是获得性能方面最好的方法,并且在应用程序中执行此操作将为您提供更大的灵活性。

        2
  •  19
  •   cabgef    15 年前

    这里有一个更详细的示例函数,我不记得是从哪里得到的(几年前),或者如果我修改了它,否则我将包括适当的属性:

    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) = 0  
                 AND CHARINDEX('..',@email) = 0  
                 AND CHARINDEX(',',@email) = 0  
                 AND RIGHT(@email,1) between 'a' AND 'z'  
                   SET @valid=1  
         RETURN @valid  
    END  
    
        3
  •  4
  •   James    8 年前

    答案很好!基于这些建议,我提出了一个结合最佳2个答案的简化函数。

    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 '%_@%_.__%' THEN 1 ELSE 0 END
    END
    
        4
  •  1
  •   Tony Dong    9 年前

    fnappstripnonemail在score下丢失,需要将其添加到keep值中

    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
    
        5
  •  0
  •   JasonMArcher TWE    10 年前
    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
    
        6
  •  0
  •   Alex    10 年前

    这是选择它们的最简单方法。

    使用此查询

    SELECT * FROM <TableName> WHERE [EMail] NOT LIKE '%_@__%.__%'
    
        7
  •  0
  •   Roy Gelerman    7 年前
    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 '%_@_%_.[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
    
        8
  •  0
  •   Esperento57    7 年前

    在SQL 2016或+

    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 '%.@' 
       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 = 'abcdefghijklmnopqrstuvwxyz01234567890!#$%&‘*+-/=?^_`.{|}~'
         , @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 = 'abcdefghijklmnopqrstuvwxyz01234567890-.'
         , @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
    
        9
  •  -2
  •   payonk    14 年前

    从托马拉克的书里

    select 1
    where @email not like '%[^a-z,0-9,@,.]%'
    and @email like '%_@_%_.__%'