2008-10-23 2 views
25

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

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

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

+0

возможно дубликат [Sql скрипт, чтобы найти недействительные адреса электронной почты] (http://stackoverflow.com/questions/801166/sql-script- to-find-invalid-email-addresses) – Neolisk 2015-01-28 15:28:28

ответ

42

Очень основные будет:

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 

Это соответствует все с @ в середине, предшествовали, по крайней мере один символ, а затем, по меньшей мере, два, точку и, по меньшей мере, два ДВА ,

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

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

+0

Да, у меня уже есть регулярные выражения в коде, которые делают это для меня, но мне нужно делать отчетность по таблицам с помощью zillions электронной почты и создавать агрегаты. – 2008-10-23 14:40:01

+0

Зная основные данные, которые у вас есть, вы можете придумать что-то более конкретное и соответствующее, чем я предложил для начала, но вы никогда не получите его «правильным», поскольку слово используется в теории алгоритмов. – Tomalak 2008-10-23 14:42:38

18

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

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 
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 '%[email protected]__%.__%' 
0

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

на 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 = '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 
Смежные вопросы