如何删除 SQL 服务器中奇怪的 Excel 字符?
How to remove weird Excel character in SQL Server?
从 Excel 导入时,我的数据中偶尔会出现一个奇怪的空白字符,我似乎无法摆脱它。显然,它显示为空白字符,但 SQL 服务器将其视为问号 (ASCII 63)。
declare @temp nvarchar(255); set @temp = 'carolg@c?am.com'
select @temp
returns:
?carolg@c?am.com
如何在不去掉真正的问号的情况下去掉空格?如果我查看每个“?”的 ASCII 码我得到 63 个字符,而实际上只有其中一个是真正的问号。
看看 this answer 有类似问题的人。对不起,如果这有点啰嗦:
SQL 服务器似乎通过将无法表示的字符(没有合适的替换)映射到问号来将 Unicode 扁平化为 ASCII。要复制它,请尝试打开 Character Map Windows 程序(应该安装在大多数机器上),select Arial 作为字体并找到 U+034f "Combining Grapheme Joiner"。 select 这个字符,复制到剪贴板并粘贴到下面的单引号之间:
declare @t nvarchar(10)
set @t = '͏'
select rtrim(ltrim(@t)) -- we can try and trim it, but by this stage it's already a '?'
你会得到一个问号,因为当它把这个非 ASCII 字符转换为 varchar
时,它不知道如何表示它。如前所述,要强制它接受它作为双字节字符 (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
导入的数据绝对可以做到这一点,我以前见过,而且像我上面显示的字符特别难以诊断,因为你看不到它们! 你需要创建某种清理过程来删除这些不可打印的字符(以及任何其他垃圾字符),并确保你在任何地方都使用 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
(同样的原因 "t" 在输出中显示为 0x7400
,而不是 0x0074
).有关我们为什么使用二进制排序规则的一些说明,请参阅 。
这有点乱,因为你不知道脏字符是什么,它们可能是成千上万种可能性中的一种。一种选择是使用 like
甚至 unicode()
function 遍历字符串并丢弃不在可接受字符列表中的字符串中的字符,但这可能很慢。可能是您的大部分错误字符位于字符串的开头或结尾,如果您认为可以做出这样的假设,这可能会加快此过程。
您可能需要在 SQL 服务器外部或作为 SSIS 导入的一部分构建额外的进程,如果您有大量数据要访问,则根据我在上面向您展示的内容快速删除它进口。如果您不确定执行此操作的最佳方法,最好在一个新问题中回答。
希望对您有所帮助。
从 Excel 导入时,我的数据中偶尔会出现一个奇怪的空白字符,我似乎无法摆脱它。显然,它显示为空白字符,但 SQL 服务器将其视为问号 (ASCII 63)。
declare @temp nvarchar(255); set @temp = 'carolg@c?am.com'
select @temp
returns:
?carolg@c?am.com
如何在不去掉真正的问号的情况下去掉空格?如果我查看每个“?”的 ASCII 码我得到 63 个字符,而实际上只有其中一个是真正的问号。
看看 this answer 有类似问题的人。对不起,如果这有点啰嗦:
SQL 服务器似乎通过将无法表示的字符(没有合适的替换)映射到问号来将 Unicode 扁平化为 ASCII。要复制它,请尝试打开 Character Map Windows 程序(应该安装在大多数机器上),select Arial 作为字体并找到 U+034f "Combining Grapheme Joiner"。 select 这个字符,复制到剪贴板并粘贴到下面的单引号之间:
declare @t nvarchar(10)
set @t = '͏'
select rtrim(ltrim(@t)) -- we can try and trim it, but by this stage it's already a '?'
你会得到一个问号,因为当它把这个非 ASCII 字符转换为 varchar
时,它不知道如何表示它。如前所述,要强制它接受它作为双字节字符 (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
导入的数据绝对可以做到这一点,我以前见过,而且像我上面显示的字符特别难以诊断,因为你看不到它们! 你需要创建某种清理过程来删除这些不可打印的字符(以及任何其他垃圾字符),并确保你在任何地方都使用 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
(同样的原因 "t" 在输出中显示为 0x7400
,而不是 0x0074
).有关我们为什么使用二进制排序规则的一些说明,请参阅
这有点乱,因为你不知道脏字符是什么,它们可能是成千上万种可能性中的一种。一种选择是使用 like
甚至 unicode()
function 遍历字符串并丢弃不在可接受字符列表中的字符串中的字符,但这可能很慢。可能是您的大部分错误字符位于字符串的开头或结尾,如果您认为可以做出这样的假设,这可能会加快此过程。
您可能需要在 SQL 服务器外部或作为 SSIS 导入的一部分构建额外的进程,如果您有大量数据要访问,则根据我在上面向您展示的内容快速删除它进口。如果您不确定执行此操作的最佳方法,最好在一个新问题中回答。
希望对您有所帮助。