Проверка достоверности TSQL (без регулярного выражения)
Хорошо, существует миллион регулярных выражений для проверки адреса электронной почты, но как насчет некоторой базовой проверки электронной почты, которая может быть интегрирована в TSQL-запрос для Sql Server 2005?
Я не хочу использовать процедуру или функцию CLR. Просто прямо TSQL.
Кто-нибудь уже это занялся?
Ответы
Ответ 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]_%_.__%'