如何在SQL Server中删除奇怪的Excel字符?

时间:2017-10-17 00:04:03

标签: sql-server excel special-characters data-cleaning

从Excel导入时,有一个奇怪的空白字符,我似乎无法摆脱偶尔显示在我的数据中。可见,它是一个空白字符,但SQL Server将其视为问号(ASCII 63)。

declare @temp nvarchar(255); set @temp = 'carolg@c?am.com'
select @temp

返回:

?carolg@c?am.com

如何在不摆脱真正问号的情况下摆脱空白?如果我查看每个“?”的ASCII代码实际上,我得到63个字符,其中只有一个是真正的标记。

1 个答案:

答案 0 :(得分:2)

对于有类似问题的人,请查看this answer。对不起,如果这有点长篇大论:

SQL Server似乎通过将不可表示的字符(没有合适的替换)映射到问号来将Unicode展平为ASCII。要复制它,请尝试打开Character Map Windows程序(应该安装在大多数机器上),选择Arial作为字体并找到U + 034f"组合Grapheme Joiner"。选择此字符,复制到剪贴板并将其粘贴到下面的单引号之间:

declare @t nvarchar(10)
set @t = '͏'
select rtrim(ltrim(@t)) -- we can try and trim it, but by this stage it's already a '?'

您会收到一个问号,因为在将其转换为varchar时,它不知道如何表示这个非ASCII字符。要强制它接受它作为双字节字符(nvarchar),您需要使用N''代替,如前所述。在上面的引号前添加N,问号就会消失(但原始不可见字符会保留在输出中 - ltrimrtrim不会删除它,如下所示):

declare @t nvarchar(10), 
        @s varchar(10) -- note: single-byte string
set @t = rtrim(ltrim(N'͏')) -- trimming doesn't work here either
set @s = @t 
select @s -- still outputs a question mark

导入的数据绝对可以做到这一点,我以前见过它,而上面显示的字符特别难以诊断,因为你无法看到它们!< / em>您需要创建某种清理过程来删除这些unprintables(以及任何其他垃圾字符),并确保在任何地方都使用nvarchar,否则您最终会有了这个问题。更糟糕的是,那些幻影问号将成为您无法区分合法问号的真正问号。

要查看您正在处理的字符代码,可以按如下方式转换为varbinary:

declare @t nvarchar(10)
set @t = N'͏test?'
select cast(@t as varbinary) -- returns 0x4F0374006500730074003F00

-- Returns:
-- 0x4F03  7400 6500 7300 7400 3F00
-- badchar  t    e    s    t    ?

现在摆脱它:

declare @t nvarchar(10)
set @t = N'͏test?'
select cast(@t as varbinary) -- bad char
set @t = replace(@t COLLATE Latin1_General_100_BIN2, nchar(0x034f), N'');
select cast(@t as varbinary)  -- gone!

注意我必须将字节顺序从0x4f03交换为0x034f(同样的原因&#34; t&#34;在输出中显示为0x7400,而不是0x0074 })。有关我们为何使用二进制排序规则的一些说明,请参阅this answer

这有点乱,因为你不知道脏字是什么,它们可能是成千上万种可能之一。一种选择是使用like甚至unicode() function迭代字符串,并丢弃不在可接受字符列表中的字符串中的字符,但这可能很慢。可能是你的大多数不良角色要么在字符串的开头或结尾,如果这是你认为可以做出的假设,这可能会加快这个过程。

如果要导入大量数据,您可能需要根据我上面显示的内容构建SQL Server外部或SSIS导入的一部分,以便快速删除它。如果您不确定最佳方法,那么在新问题中可能会得到最佳答案。

我希望有所帮助。