Подтвердить что ты не робот

Проверка достоверности TSQL (без регулярного выражения)

Хорошо, существует миллион регулярных выражений для проверки адреса электронной почты, но как насчет некоторой базовой проверки электронной почты, которая может быть интегрирована в TSQL-запрос для Sql Server 2005?

Я не хочу использовать процедуру или функцию CLR. Просто прямо TSQL.

Кто-нибудь уже это занялся?

4b9b3361

Ответ 1

Очень простой способ:

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

Это соответствует всем с помощью @в середине, которому предшествует хотя бы один символ, за которым следует по крайней мере два, точка и минимум два для TLD.

Вы можете написать больше шаблонов LIKE, которые будут делать более конкретные вещи, но вы никогда не сможете сопоставить все, что может быть адресом электронной почты, не позволяя проскальзывать через то, что нет. Даже с регулярными выражениями вам сложно делать это правильно. Кроме того, даже сопоставление в соответствии с самыми буквами RFC соответствует конструкциям адресов, которые не будут приниматься/использоваться большинством систем электронной почты.

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

Ответ 2

Вот примерная функция для этого, немного более подробная, я не помню, откуда я получил это (много лет назад), или если бы я ее модифицировал, в противном случае я бы включил правильную атрибуцию:

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  

Ответ 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 '%[email protected]%_.__%' THEN 1 ELSE 0 END
END

Ответ 4

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

Это самый простой способ выбрать их.

Использовать этот запрос

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

Ответ 6

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

Ответ 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 '%[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

Ответ 8

В 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 '%[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 = '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

От увольнения Томалака

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