从Excel导入时,有一个奇怪的空白字符,我似乎无法摆脱偶尔显示在我的数据中。可见,它是一个空白字符,但SQL Server将其视为问号(ASCII 63)。
declare @temp nvarchar(255); set @temp = 'carolg@c?am.com'
select @temp
返回:
?carolg@c?am.com
如何在不摆脱真正问号的情况下摆脱空白?如果我查看每个“?”的ASCII代码实际上,我得到63个字符,其中只有一个是真正的标记。
答案 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
,问号就会消失(但原始不可见字符会保留在输出中 - ltrim
和rtrim
不会删除它,如下所示):
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导入的一部分,以便快速删除它。如果您不确定最佳方法,那么在新问题中可能会得到最佳答案。
我希望有所帮助。