TSQL 电子邮件验证(无正则表达式)

问题描述 投票:0回答:10

好吧,有一百万个正则表达式用于验证电子邮件地址,但是一些可以集成到 Sql Server 2005 的 TSQL 查询中的基本电子邮件验证怎么样?

我不想使用 CLR 过程或函数。 只是直接的 TSQL。

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

sql-server t-sql email-validation
10个回答
56
投票

非常基本是:

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 的字母进行匹配,也会匹配大多数电子邮件系统不会接受/使用的地址结构。

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


20
投票

这是一个更详细的示例函数,我不记得我从哪里得到这个(几年前),或者我是否修改过它,否则我会包含正确的归属:

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
投票

很好的答案! 根据这些建议,我想出了一个结合了最好的 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

3
投票

在 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

1
投票

FnAppStripNonEmail 在分数下缺失,需要将其添加到保留值中

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

1
投票
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

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
投票

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

使用此查询

SELECT * FROM <TableName> WHERE [EMail] NOT LIKE '%_@__%.__%'

0
投票

从 sql 2008 开始 patindex 删除重复查找

来自:https://www.codelabs365.com/sql-cookbook/sql-server/tsql-validate-and-check-email-address-using-like-or-patindex-function/

CREATE FUNCTION ValidateEmail (@Email VARCHAR(100))
RETURNS VARCHAR(3)
AS
BEGIN
    RETURN (
        SELECT CASE
            WHEN ISNULL(@Email, '') = '' THEN 'No'
            WHEN @Email LIKE '% %' THEN 'No'
            WHEN PATINDEX('%["(),:;<>]%', @Email) <> 0 THEN 'No'
            WHEN SUBSTRING(@Email, CHARINDEX('@', @Email), LEN(@Email)) LIKE ('%[!#$%&*+/=?^`_{|]%') THEN 'No'
            WHEN (LEFT(@Email, 1) LIKE ('[-_.+]') OR RIGHT(@Email, 1) LIKE ('[-_.+]')) THEN 'No'
            WHEN (@Email LIKE '%[%' OR @Email LIKE '%]%') THEN 'No'
            WHEN @Email LIKE '%@%@%' OR @Email LIKE '%@%..%' THEN 'No'
            WHEN PATINDEX('_%@_%.__%', @Email) = 0 THEN 'No'
            ELSE 'Yes'
        END
    )
END;

虽然个人我会使用

trim(@Email) = '' THEN 'No'
而不是
@Email LIKE '% %' THEN 'No'


-2
投票

来自托马拉克的精选

select 1
where @email not like '%[^a-z,0-9,@,.]%'
and @email like '%_@_%_.__%'
© www.soinside.com 2019 - 2024. All rights reserved.