如何在 SQL 中处理 Unicode 替换字符 � (0xFFFD / 65533)

Posted

技术标签:

【中文标题】如何在 SQL 中处理 Unicode 替换字符 � (0xFFFD / 65533)【英文标题】:How to deal with Unicode replacement character � (0xFFFD / 65533) in SQL 【发布时间】:2015-07-26 05:52:59 【问题描述】:

我几乎不知道一周前就存在 Unicode 替换字符 (�)。现在我了解到至少在 SQL 中似乎有一些非常特殊和奇怪的逻辑围绕着它。例如:

select replace(N'bl' + NCHAR(65533) + N'rt', NCHAR(65533), N'X')

返回 bl�rt 而不是 blXrt。并且:

select CHARINDEX(NCHAR(65533), N'b' + NCHAR(65533) + N't')

返回 0 而不是 2。我只是想确定表中的哪些字符串包含此字符,但找不到直接的方法。这个人物的待遇好诡异,一定有更多可以了解的地方。行为在哪里定义,更具体地说,在 MS SQL Server 数据库中查找包含此字符的字符串的最简单方法是什么?

编辑 对于任何尝试答案的人,我建议根据以下数据测试您的答案:

create table Test([Value] nvarchar(100) not null)
insert into Test([Value]) values('b' + NCHAR(65533) + 't')
insert into Test([Value]) values('b?t')
insert into Test([Value]) values('bat')

【问题讨论】:

这是否取决于数据库或表的排序规则?只是出于好奇,您使用的是什么排序规则? 该列是 nvarchar(100) (所以它是 Unicode)并且没有应用特定的排序规则,所以我猜它是从数据库中获取排序规则。数据库排序规则是 SQL_Latin1_General_CP850_CI_AS。 @Jodrell 它与 TSQL 相关,我认为我可以在 C# 中识别包含此字符的字符串,但我不能在简单的 TSQL 代码中这样做,因为它是面向批处理的。 我改变主意了,我认为你暴露了一个不令人满意的边缘案例。 奇怪的是SELECT CHARINDEX(NCHAR(65533), NCHAR(65533)); 是正确的。 【参考方案1】:

Krzysztof Kozielczyk 写道,有效的 unicode 字符需要转换为二进制字符串才能被替换,因此这可能是您最初问题的答案。

SELECT REPLACE(N'test' + NCHAR(65533) 
COLLATE Latin1_General_BIN, NCHAR(65533) COLLATE Latin1_General_BIN, '')

上面的代码还指出了如何定位具有有效 unicode 字符的字符串,但它是一种变通方法而不是解决方案。 source

【讨论】:

明确排序规则似乎确实可以使所有功能按预期工作。

以上是关于如何在 SQL 中处理 Unicode 替换字符 � (0xFFFD / 65533)的主要内容,如果未能解决你的问题,请参考以下文章

替换 T-SQL 中的 Unicode 字符

通过 Windows 批处理文件将字符串替换为文本文件中的 unicode

如何从雪花中删除 Unicode 替换字符

如何在 perl 正则表达式替换命令中使用 unicode 字符?

如何替换 Java 中不可打印的 Unicode 字符?

Vim 用 unicode 字符替换