Ok, il y a un million d'expressions régulières pour valider une adresse e-mail, mais que diriez-vous d'une validation de base par e-mail qui peut être intégrée dans une requête TSQL pour Sql Server 2005?
Je ne veux pas utiliser une procédure ou une fonction CLR. TSQL juste droit.
Quelqu'un a-t-il déjà abordé cela?
Très basique serait:
SELECT
EmailAddress,
CASE WHEN EmailAddress LIKE '%_@_%_.__%'
AND EmailAddress NOT LIKE '%[any obviously invalid characters]%'
THEN 'Could be'
ELSE 'Nope'
END Validates
FROM
Table
Cela correspond à tout avec un @ au milieu, précédé d'au moins un caractère, suivi d'au moins deux, d'un point et d'au moins deux pour le TLD.
Vous pouvez écrire plus de modèles LIKE
qui font des choses plus spécifiques, mais vous ne pourrez jamais faire correspondre tout ce qui pourrait être une adresse e-mail sans laisser passer les choses qui ne le sont pas. Même avec des expressions régulières, vous avez du mal à bien faire les choses. De plus, même la correspondance selon les lettres mêmes du RFC correspond aux constructions d'adresses qui ne seront pas acceptées/utilisées par la plupart des systèmes de messagerie.
Faire cela au niveau de la base de données est peut-être de toute façon la mauvaise approche, donc un contrôle de base comme indiqué ci-dessus peut être le meilleur que vous puissiez obtenir en termes de performances, et le faire dans une application vous offrira une bien plus grande flexibilité.
Voici un exemple de fonction pour cela qui est un peu plus détaillé, je ne me souviens pas d'où je l'ai obtenu (il y a des années), ou si je l'ai modifié, sinon j'inclurais l'attribution appropriée:
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
Excellentes réponses! Sur la base de ces recommandations, j'ai trouvé une fonction simplifiée qui combine les 2 meilleures réponses.
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
Sur SQL 2016 ou +
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
FnAppStripNonEmail manquant sous le score, il faut l'ajouter aux valeurs de conservation
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
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
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
C'est le moyen le plus simple de les sélectionner.
Utilisez cette requête
SELECT * FROM <TableName> WHERE [EMail] NOT LIKE '%_@__%.__%'