删除字符串结尾的不可见空字符

A_V*_*A_V 3 sql-server varchar sql-server-2016

由于未知原因,我的 VARCHAR(1000) 列之一中的许多字符串都以不可见字符结尾。

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;
Run Code Online (Sandbox Code Playgroud)

select * from @BrokenStringTable for json auto;语句的输出如下所示:

[{"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??"}]
Run Code Online (Sandbox Code Playgroud)

如何检测表中哪些记录包含这些字符?似乎使用 charindex、where+like 和任何其他正常解决方案都不适用于这些。

Aar*_*and 5

其中一个我喜欢大大的原因convert()cast()convert()更加扩展。例如,您可以使用样式编号将二进制值按原样转换为字符串。所以 if3F00总是有问题的字符:

SELECT CASE 
  WHEN CONVERT(nvarchar(max), @BrokenString, 1) LIKE N'%3F00' 
  THEN 'borked' END;
Run Code Online (Sandbox Code Playgroud)

结果:

borked
Run Code Online (Sandbox Code Playgroud)

因此,您可以使用以下方法找到所有违规行(这不会设置任何速度记录):

SELECT ... FROM dbo.table 
WHERE CONVERT(nvarchar(max), column) LIKE N'%3F00';
Run Code Online (Sandbox Code Playgroud)