sql-server - LIKE 忽略魔法 Unicode 字符

标签 sql-server tsql unicode sql-like

SQL Server 2008 R2

 create table #test (c1 nvarchar(5) not null)

  insert into #test values 
  (N'aaa'),
  (nchar(65533)),
  (N'bbb')

  select * from #test where c1 like N'%�%'
  select * from #test where c1 like N'%'+nchar(65533)+N'%'

结果是
c1
----
aaa
�
bbb

为什么?我还没有在 MSDN 中找到关于这个案例的任何说明。

最佳答案

该字符(以及许多其他字符,取决于所使用的排序规则版本)恰好没有定义排序权重。它实际上什么都不是。因此,无论您有 1 个还是 100 个实例,它对二进制排序规则以外的任何东西都是不可见的。意思是,以下WHERE谓词:

LIKE N'%' +  NCHAR(0xFFFD) + N'%'

LIKE N'%' +  NCHAR(0xFFFD) +  NCHAR(0xFFFD) + N'%'

LIKE N'%' +  NCHAR(0xFFFD) +  NCHAR(0xFFFD) +  NCHAR(0xFFFD) + N'%'

等等,都等价于以下内容:
LIKE N'%%'

这就是为什么您返回所有 3 行的原因。

这并不意味着这个字符应该没有排序权重。它实际上在 Unicode 中被定义为具有权重,但出于某种原因,微软留下了相当多的字符根本没有任何排序权重(尽管每一个新的排序规则版本,缺少排序权重的字符总数都在减少,最新的是版本 140 排序规则,随 SQL Server 2017 一起提供,仅适用于日语排序规则)。

对于没有排序权重的任何字符,匹配它的唯一方法是使用二进制排序规则。二进制排序规则是以 _BIN 结尾的排序规则或 _BIN2 ,但只能使用 _BIN2排序规则,因为它们排序正确,而较旧的 _BIN校对没有。例如:
SELECT * FROM #test WHERE c1 LIKE N'%�%' COLLATE Latin1_General_100_BIN2;

返回:

c1
----



另外,我使用以下内容进行了测试,它们返回了所有 3 行:
  • Latin1_General_CS_AS_KS_WS
  • Latin1_General_100_CS_AS_KS_WS_SC

  • 所以,以下应该是好的:
  • Latin1_General_BIN2
  • 拉丁语1_General_100_BIN2

  • 此外,最好使用可用于您尝试使用的排序规则的最高排序规则版本。例如,使用 Latin1_General_100_*而不是 Latin1_General_* , 等等。使用以下查询查找您的实例上可用的排序规则:

    SELECT col.*
    FROM   sys.fn_helpcollations() col
    ORDER BY col.[name];
    

    关于sql-server - LIKE 忽略魔法 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27554244/

    相关文章:

    sql-server - 使用 SSMS 将 CSV 导入 SQL Azure 数据库

    sql-server - 如何对SQL Server中的多列数据进行排名?

    sql - 寻找 T-SQL 脚本来删除 SQL 作业

    sql-server - 如何检查 SQL 表是否被锁定以供查询?

    c# - 在 LINQ 查询中使用内置的 sql 函数?

    pdf - 带有 PDF 和 Unicode(希腊语)字符的 Jasper 报告

    Python:如何读取和解析 unicode utf-8 文本文件?

    sql-server - SSIS 包不会将数据写入 excel 目标

    sql - 如何将数据从一个表复制到另一台服务器上的另一个表?

    string - 将 unicode 转换为“java”