2008-10-23 93 views
25

好吧,有一百萬個正則表達式用於驗證電子郵件地址,但如何將一些基本電子郵件驗證集成到SQL Server 2005的TSQL查詢中?TSQL電子郵件驗證(無正則表達式)

我不想使用CLR過程或函數。只需直接TSQL。

有人已經解決了這個問題嗎?

+0

可能重複[SQL腳本找到無效的電子郵件地址(http://stackoverflow.com/questions/801166/sql-script-找到無效的電子郵件地址) – Neolisk 2015-01-28 15:28:28

回答

42

非常基本是:

​​

此相匹配的一切在中間的@,由至少一個字符開頭,後面至少有兩個,一個點和至少兩個用於TLD 。

你可以編寫更多的LIKE模式來做更具體的事情,但你永遠無法匹配所有可能成爲電子郵件地址的東西,而不會漏過那些不是的東西。即使使用正則表達式,你也很難做到這一點。此外,甚至根據RFC的字母匹配地址結構,這些地址結構將不被大多數電子郵件系統接受/使用。

在數據庫級別執行此操作可能是錯誤的方法,因此如上所述的基本健全性檢查可能是您獲得性能最佳的最佳方法,並且在應用程序中執行此操作可爲您提供更大的靈活性。

+0

是的,我已經有代碼的正則表達式爲我做這件事,但我需要做無數次的電子郵件報表,並拿出聚合。 – 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 
-2

從託默勒格的slelect

select 1 
where @email not like '%[^a-z,0-9,@,.]%' 
and @email like '%[email protected]_%_.__%' 
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下得分缺失,需要將其添加到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 
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 
相關問題