为啥 SQL Server 在 equals 语句中忽略表情符号?

Posted

技术标签:

【中文标题】为啥 SQL Server 在 equals 语句中忽略表情符号?【英文标题】:Why is SQL Server ignoring emoji's in equals statement?为什么 SQL Server 在 equals 语句中忽略表情符号? 【发布时间】:2016-10-10 19:27:06 【问题描述】:

今天遇到一个有趣的问题,想知道该行为背后的原因。我有一个包含用户名的用户表,我对此进行查询以提取唯一用户,然后使用所有散列和咸味进行密码检查。

但是,如果我将表情符号放入查询中,用户仍会退出数据库,我想知道为什么以及需要应用什么设置。我正在使用 EF,但我测试了原始 T-SQL 并且行为是相同的,所以 EF 不是罪魁祸首。

SELECT TOP 1 * 
FROM Users 
WHERE username = N'someuser' --Works as expected

SELECT TOP 1 * 
FROM Users 
WHERE username = N'some????user????' --ALSO WORKS!

我可以将表情符号放在任何地方,想放多少就放多少,用户仍然会返回。我显然可以将 C# 代码放在适当的位置,以便进行额外的检查,所以这个问题在那里可以解决,但我希望它在数据库级别解决,因为可能有许多其他查询可以进行字符串比较。

密码中的表情符号不是问题,因为散列和加盐将在 C# 中应用,所以密码中的表情符号很好。

【问题讨论】:

数据库的排序规则设置是什么? SQL_Latin1_General_CP1_CI_AS CP1 表示code page 1252,我假设该代码页中没有的任何内容都将被完全忽略。 @ErikPhilips 这也是我的猜测......虽然我不知道具体细节,但默认情况下,引擎可能会忽略不属于已知排序规则的任何内容。尝试在整理设置文档/文章中四处寻找线索。 文字'some????user????' 有这个效果。因为它被视为some??user??。因此,我已将您的示例更改为 N'some????user????' - 确实如此。 【参考方案1】:

您使用的排序规则不支持表情符号字符的比较;所以它忽略了它们。如果您希望事情按您通常期望的那样工作,您可以在比较期间使用特定的排序规则:

select *
from (values
    (N'some?user?', N'someuser')
  , (N'someuser', N'someuser')
  , (N'some?user?', N'some?user?')
) as a (L, R)
where a.L = a.R collate Latin1_General_100_CI_AS_SC;

有关详细信息,请参阅 MSDN 文章 Collation and Unicode Support。

【讨论】:

以上是关于为啥 SQL Server 在 equals 语句中忽略表情符号?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2016 - 为啥我需要为我的选择语句指定一个根元素

为啥在 equals 方法中必须有 2 个 return 语句

sql server 2008同一个语句查询,为啥时快时慢

sql server 2008同一个语句查询,为啥时快时慢

为啥sqlserver查询不到数据

为啥在SQL语句的GROUP BY里面不可以使用别名