需要注意的是,这会发现在姓名和电子邮件地址中都有效的字符但在您的系统中似乎无效,您应该使用以下LIKE 语句:
WHERE tab.col LIKE '%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2;
这里重要的是COLLATE Latin1_General_100_BIN2(除非该字段已经使用二进制排序规则)。但是如果该字段没有使用二进制排序规则,那么在此处不为LIKE 谓词指定一个将丢失诸如ñ 和其他重音字符,因为它们通常等同于非重音字符(例如n = @ 987654328@).
例子:
SELECT col
FROM (VALUES ('©Johñ'),
('{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»" } }'),
('{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones" } }'),
('{ }'),
('f_f'),
('g-g'),
('Johñ f')
) tab(col)
WHERE tab.col LIKE '%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2;
使用COLLATE 子句标识'Johñ f' 行,但没有COLLATE,该行似乎是“有效的”。
或者,如果你有两个:
- Unicode 数据(即
NVARCHAR / NCHAR 字段)
- 一个接受真实世界数据的系统(并且不会错误地拒绝包含非美国英语字符的姓名和电子邮件地址,或将它们转换为美国英语等效字符)
然后,T-SQL LIKE 运算符无法工作,因为许多语言中的字母种类繁多。在这种情况下,您将需要一个正则表达式,因为它们可以处理字符类,它们是字符的逻辑分组。当然,RegEx 并不在 T-SQL 中原生提供,但您仍然可以通过 SQLCLR 获得此功能。您可以找到很多关于如何编写代码的示例,或者您可以下载SQL# 库的免费版本(我创建的,但大多数 RegEx 函数 - 以及许多其他函数 - 都是免费的),其中包括RegEx_IsMatch函数可以使用如下:
SELECT tab.col,
CASE WHEN tab.col LIKE N'%[^-a-zA-Z0-9.,@:{}" _]%' COLLATE Latin1_General_100_BIN2
THEN 1 ELSE 0 END AS [LikeOperator],
SQL#.RegEx_IsMatch(tab.col, N'[\W-[-\{\} @:",.]]+', 1, N'IgnoreCase')
AS [RegEx_IsMatch]
FROM (VALUES (N'©Johñ'),
(N'{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»" } }'),
(N'{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones" } }'),
(N'{ }'),
(N'f_f'),
(N'g-g'),
(N'k,k'),
(N'WIDE'),
(N'simple-email@place01.co'),
(N'Johñ f')
) tab(col);
返回:
col LIKE RegEx
----------------------- ----- ------
©Johñ 1 1
{ "email_address":"fakemail@mail.com", "values":{ "LNAME":"SmÌth»" } } 1 1
{ "email_address":"fakemail2@mail.com", "values":{ "LNAME":"Jones" } } 0 0
{ } 0 0
f_f 0 0
g-g 0 0
k,k 0 0
WIDE 1 0
simple-email@place01.co 0 0
Johñ f 1 0
[\W-[-\{\} @:",.]]+ 模式的含义是:一个或多个字符 ([]+) 是“非单词”字符 (\W) 除了 (-[]) 以下列表可以:-、{、}、、@、:、"、, 和 .。