Por um motivo desconhecido, muitas strings em uma das minhas colunas VARCHAR(1000) foram encerradas com caracteres invisíveis.
declare @BrokenString varbinary(max)=0x6D0079002000620075006700670065006400200073007400720069006E00670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003F003F00;
select cast(@BrokenString as nvarchar(max)) -- returns 'my bugged string'
select cast(@BrokenString as nvarchar(max)) + ' is bugged' -- still returns 'my bugged string' !
declare @BrokenStringTable table (Brokey nvarchar(max));
insert into @BrokenStringTable
select cast(@BrokenString as nvarchar(max));
select * from @BrokenStringTable for json auto;
A saída da select * from @BrokenStringTable for json auto;
instrução se parece com isso:
[{"Brokey":"my bugged string\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000??"}]
Como posso detectar quais registros na minha tabela contém esses caracteres? Parece que usar charindex, where+like e quaisquer outras soluções normais simplesmente não funcionam com elas.
Uma das razões pelas quais eu prefiro muito
convert()
maiscast()
é queconvert()
é muito mais extensível. Por exemplo, você pode usar um número de estilo para converter um valor binário em uma string como está . Então, se3F00
é sempre o personagem problemático:Resultado:
Assim, você pode encontrar todas as linhas ofensivas (isso não definirá nenhum recorde de velocidade) usando:
Depois de analisar a resposta de Aaron, encontrei uma maneira de remover todos os caracteres nulos 0x000 \u0000. Esta técnica usa um monte de conversões como varchar(max) e, como Aaron disse, não definirá nenhum recorde de velocidade, mas funcionou bem.
Eu o envolvi em duas funções para que ele seja usado assim:
O
FixedColumn
conterá a string inteira sem os caracteres nulos que anteriormente quebravam a exibição correta da minha string.Aqui está um exemplo
Aqui está o código para as funções