Qual é a melhor maneira de verificar se um campo VARCHAR possui caracteres não ASCII?
CHAR(1)
através CHAR(31)
e CHAR(127)
através CHAR(255)
.
Tentei usar PATINDEX
e me deparei com o seguinte problema.
A verificação do intervalo inferior funcionou corretamente.
SELECT *
FROM mbrnotes
WHERE PATINDEX('%[' + CHAR(1)+ '-' +CHAR(31)+']%',LINE_TEXT) > 0
Meus dados tinham três registros com 0x1E e todos os três foram retornados.
Mas quando eu verifico apenas o intervalo superior:
SELECT *
FROM mbrnotes
WHERE PATINDEX('%[' + CHAR(127)+ '-' +CHAR(255)+']%',LINE_TEXT) > 0
Ele retorna perto de todos os registros da tabela (tabela contagem 170737 e retornou contagem 170735) e como meus dados não tinham nenhum valor nesse intervalo eu acho que não deveria ter retornado nenhum registro.
Os intervalos na sintaxe do padrão usam as regras de classificação do seu agrupamento.
Use uma cláusula de agrupamento binário para que o intervalo seja ordenado por código de caractere.
(Eu também mudei para
LIKE
porque acho isso mais óbvio do quePATINDEX > 0
)Se você realmente quiser ver os personagens ofensivos e estiver em uma versão com a
TRANSLATE
função, você pode usar algo como o abaixoVocê pode usar esse resultado em uma segunda chamada
TRANSLATE
para preservar apenas os caracteres "bons".Se você é como eu e se cansou ao longo dos anos procurando esses caracteres nos dados terríveis da sua empresa, você pode usar esta função ou reescrevê-la para seu próprio propósito. É reconhecidamente prolixo, mas dá um passo extra de identificar caracteres especiais, se você quiser - descomente as linhas 19 - 179 para fazê-lo.
Se a string não contiver valores ASCII não imprimíveis ou estendidos - ela retornará NULL.
E então, chame assim:
Saída de amostra:
Ou