如果您保证只使用美国英语字母的26个字母(大写和小写版本),那么可以肯定,您可以避免使用LIKE
和/或PATINDEX
使用简单的范围标记[a-z]
(您不会使用不区分大小写的排序规则时,需要使用大写字母“ Z”)。
但是,如果您可能会发现在美国字母中找不到的字符,但在各种代码页/排序规则中都可以找到用于VARCHAR
数据的字符(例如Þ
=拉丁大写字母“ Thorn” =SELECT CHAR(0xDE)
),那么您可能需要在字符类中包括这些字符:[a-z0-9, Þ]
。当然,这些多余的字符将基于每个代码页。
另外,请注意排序规则类型(SQL Server与Windows)和敏感度设置(区分大小写,重音等,敏感与不敏感)都会影响特定范围内的字符。例如,SQL Server排序规则以与Windows排序规则相反的顺序对大写和小写字母进行排序。意思是,假设两种类型的归类均区分大小写,则一个将做AaBb...
,而另一种将做aAbB...
。结果将是它们a
中A-Z
的一个在另一个的范围内。并且范围范围a-Z
将不匹配二进制归类中的任何字符(一个以_BIN
或结尾的字符_BIN2
_BIN
假设的值A
是65且,但请勿使用),a
是97,因此它是97到65之间的无效范围;-)。这里有太多变化,无法在此处提供示例,因此我将尝试在不久的某个时候在我的博客上发布详细的说明(然后使用其链接对其进行更新)。但是,如果要严格只接受美国英语字符(即使您可能会从其他语言获得有效的字母),那么最好的选择可能是使用以下模式和排序规则:
LIKE '%[^A-Za-z0-9, ]%' COLLATE Latin1_General_100_BIN2
现在,如果您正在支持NVARCHAR
数据并且可以从各种语言中获取“单词”字符,那么T-SQL将没有太大帮助,因为它没有真正的方法来区分这些东西。在这种情况下,应使用正则表达式(RegEx)(特别是Replace
方法/函数),并且只能通过SQLCLR使用。下面显示了一个示例,该示例替换了几个“特殊”字符,但保留了至少一种语言中的所有有效字母:
DECLARE @Test NVARCHAR(500);
SET @Test = N'this$is%a<>TEST,;to}⌡↕strip╞╟╚══¶out_ç_ƒ▀ special-ij-೫-chars-舛-დ-א-B';
SELECT SQL#.RegEx_Replace4k(@Test, N'[\W\p{Pc}-[,]]', N' ', -1, 1, NULL);
返回值:
this is a TEST, to strip out ç ƒ special ij ೫ chars 舛 დ א B
RegEx表达式的意思是:
\W
=正则表达式“转义”,表示“任何非单词字符”
\p{Pc}
=“标点符号,连接器”的Unicode“类别”(仅因为\W
转义明确排除了此“类别”,才需要匹配)
-[,]
=类减法(由于逗号包含在\W
转义中,因此需要将逗号排除为特殊字符之外的匹配项)
您只需发出以下命令即可更新表:
UPDATE tbl
SET tbl.field = SQL#.RegEx_Replace4k(tbl.field, N'[\W\p{Pc}-[,]]', N' ', -1, 1, NULL)
FROM tbl
WHERE SQL#.RegEx_IsMatch4k(tbl.field, N'[\W\p{Pc}-[,]]', 1, NULL) = 1;
请注意,对于这些示例,我使用了我创建的SQLCLR函数的免费版本SQL#库中提供的两个函数(但是,这些都是免费的)。另请注意,由于使用NVARCHAR(4000)
而不是NVARCHAR(MAX)
参数类型,因此我使用了更快的“ 4k”版本。如果您的数据使用NVARCHAR(MAX)
,则只需从函数名称中删除“ 4k”。
另请参阅: