2008-10-23 4 views
25

OK, istnieje milion wyrażeń do sprawdzenia poprawności adresu e-mail, ale co z podstawową weryfikacją poczty e-mail, która może zostać zintegrowana z zapytaniem TSQL dla Sql Server 2005?Sprawdzanie poprawności poczty e-mail (bez wyrażeń regularnych)

Nie chcę używać procedury lub funkcji CLR. Po prostu proste TSQL.

Czy ktoś już to zmierzył?

+0

możliwe duplikat [skrypt SQL, aby znaleźć nieprawidłowych adresów e-mail] (http://stackoverflow.com/questions/801166/sql-script- to-find-invalid-email-addresses) – Neolisk

Odpowiedz

42

Bardzo podstawowym będzie:

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 

Dopasowuje wszystko ze znakiem @ w środku, poprzedzony co najmniej jeden znak, a następnie przez co najmniej dwie, kropka i co najmniej dwóch dla TLD .

Możesz napisać więcej wzorów LIKE, które wykonują więcej konkretnych czynności, ale nigdy nie będziesz w stanie dopasować wszystkiego, co może być adresem e-mail, nie pozwalając jednak przeskoczyć rzeczy, które nie są. Nawet przy wyrażeń regularnych masz trudności z robieniem tego poprawnie. Dodatkowo, nawet dopasowanie zgodne z literami RFC dopasowuje konstrukcje adresowe, które nie będą akceptowane/używane przez większość systemów pocztowych.

Wykonanie tego na poziomie bazy danych jest być może błędnym podejściem, więc podstawowa kontrola poprawności, jak wskazano powyżej, może być najlepsza z punktu widzenia wydajności, a wykonanie jej w aplikacji zapewni znacznie większą elastyczność.

+0

Tak, już mam wyrażenia regularne w kodzie robiącym to dla mnie, ale muszę robić raporty na tabelach z milionami e-maili i wymyślić agregaty. –

+0

Znając swoje podstawowe dane, możesz wymyślić coś bardziej konkretnego i odpowiedniego niż to, co sugerowałem na początek, ale nigdy nie uzyskasz "poprawności", ponieważ słowo to jest używane w teorii algorytmów. – Tomalak

+0

Widzę, że dodałeś "niepodobny"% [jakiekolwiek oczywiście nieprawidłowe znaki]% ".Z tego, czego się dowiedziałem o specyfikacji, nie jestem pewien, czy rzeczywiście istnieją klawisze na klawiaturze, które technicznie nie mogą być interpretowane jako ważne w adresie. –

18

Oto funkcja próbka tego, że jest trochę bardziej szczegółowy, nie pamiętam, gdzie mam to od (rok temu), albo jeśli zmodyfikowany go, inaczej bym to prawidłowe Uznanie autorstwa:

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

Cześć cabgef, To jest najlepsze rozwiązanie, które podałeś . Czy możesz mi powiedzieć, co robi "fnAppStripNonEmail"? –

+3

Potrzebowałem dodać warunek 'AND CHARINDEX ('', @ email) = 0', aby sprawdzić spacje w środku adresu e-mail. –

+0

Wiem, że jest to stary post, ale dla innych użytkowników - powoduje to błąd: "Przekroczono maksymalny zapisany procedura, funkcja, wyzwalacz lub poziom zagnieżdżenia widoku (limit 32)" – user1948635

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

jest to najprostszy sposób, aby je zaznaczyć.

Użyj tego zapytania

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

FnAppStripNonEmail brakuje pod wynik, trzeba dodać ją do Zatrzymanie wartości

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

Wielkie odpowiedzi! Na podstawie tych zaleceń opracowałem uproszczoną funkcję, która łączy najlepsze 2 odpowiedzi.

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

na SQL 2016 lub +

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 
Powiązane problemy