一尘不染

如何检查非 Ascii 字符

sql-server

检查 VARCHAR 字段是否包含非 Ascii 字符的最佳方法是什么?
CHAR(1)彻头彻尾。CHAR(31) CHAR(127)CHAR(255)

我尝试使用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),并且由于我的数据在此范围内没有任何值,我认为它应该没有返回任何记录。


阅读 72

收藏
2022-11-18

共1个答案

一尘不染

模式语法中的范围使用排序规则的排序规则。

使用二进制整理子句,以便范围按字符代码排序。

(我也将其更改为,LIKE因为我发现它比 更明显PATINDEX > 0

SELECT *
FROM mbrnotes
WHERE LINE_TEXT COLLATE Latin1_General_100_BIN2 
     LIKE '%[' + CHAR(0)+ '-' +CHAR(31) + CHAR(127)+ '-' +CHAR(255)+']%'  

如果您真的想查看有问题的字符并且您使用的是具有该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
2022-11-18