检查 VARCHAR 字段是否包含非 Ascii 字符的最佳方法是什么? CHAR(1)彻头彻尾。CHAR(31) CHAR(127)CHAR(255)
CHAR(1)
CHAR(31)
CHAR(127)
CHAR(255)
我尝试使用PATINDEX并遇到了以下问题。
PATINDEX
检查较低的范围工作正常。
SELECT * FROM mbrnotes WHERE PATINDEX('%[' + CHAR(1)+ '-' +CHAR(31)+']%',LINE_TEXT) > 0
我的数据有 0x1E 的三个记录,所有三个都返回了。
但是当我只检查上限时:
SELECT * FROM mbrnotes WHERE PATINDEX('%[' + CHAR(127)+ '-' +CHAR(255)+']%',LINE_TEXT) > 0
它返回接近表中的所有记录(表计数 170737 并返回计数 170735),并且由于我的数据在此范围内没有任何值,我认为它应该没有返回任何记录。
模式语法中的范围使用排序规则的排序规则。
使用二进制整理子句,以便范围按字符代码排序。
(我也将其更改为,LIKE因为我发现它比 更明显PATINDEX > 0)
LIKE
PATINDEX > 0
SELECT * FROM mbrnotes WHERE LINE_TEXT COLLATE Latin1_General_100_BIN2 LIKE '%[' + CHAR(0)+ '-' +CHAR(31) + CHAR(127)+ '-' +CHAR(255)+']%'
如果您真的想查看有问题的字符并且您使用的是具有该TRANSLATE功能的版本,您可以使用类似下面的内容
TRANSLATE
DECLARE @WhiteListedCharacters NVARCHAR(1000) = ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' SELECT text, REPLACE( TRANSLATE( text, @WhiteListedCharacters COLLATE Latin1_General_100_BIN2, REPLICATE( LEFT(@WhiteListedCharacters,1), LEN(@WhiteListedCharacters))), LEFT(@WhiteListedCharacters,1), '') AS BadChars FROM sys.messages WHERE language_id = 1038
然后,您可以在第二次调用中使用该结果TRANSLATE来仅保留“好”字符。
DECLARE @WhiteListedCharacters NVARCHAR(1000) = ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' SELECT text, BadChars, Cleaned = REPLACE( TRANSLATE( text COLLATE Latin1_General_100_BIN2, BadChars, REPLICATE(N'ψ', LEN(BadChars)) ), N'ψ', N'') FROM sys.messages CROSS APPLY ( SELECT REPLACE( TRANSLATE( text, @WhiteListedCharacters COLLATE Latin1_General_100_BIN2, REPLICATE( LEFT(@WhiteListedCharacters,1), LEN(@WhiteListedCharacters + '-') - 1)), LEFT(@WhiteListedCharacters,1), '') AS BadChars ) ca WHERE language_id = 1038