SQL Server 2014 LIKE with 4 B wide character returns 整个 table

SQL Server 2014 LIKE with 4 B wide character returns the entire table

我很难理解为什么 SELECTLIKE 条件在 4 B 宽表情符号 (http://emojipedia.org/eyes/) returns [=44] 中的所有行=].

-- The DB collation is Finnish_Swedish_CI_AS
CREATE TABLE #Test 
(
     Number int identity,
     Value nvarchar(20) NOT NULL
);
GO

INSERT INTO #Test VALUES ('');
INSERT INTO #Test VALUES ('a');
INSERT INTO #Test VALUES ('b');
INSERT INTO #Test VALUES ('c');
INSERT INTO #Test VALUES (''); -- should be http://emojipedia.org/eyes/
GO

select * from #Test where Value like '%%'
select * from #Test where Value like N'%%'
GO

DROP TABLE #Test;
GO

第一个 select 的结果是单个表情符号行。但是,第二个 select 的结果是所有行,其中字符串被标记为带有 N 前缀的 UNICODE。

为什么第二个 select 匹配 table 中的所有行?

实际场景 我有一个网络应用程序,用户可以在其中搜索目录,如果他们搜索表情符号,则会返回整个 table,而不是正确的匹配的行。

ASP.NET MVC 5 web application <-> Web Api 2 <-> EF -> SQL Server

Update 我的测试 SQL 不正确,因为@deroby 指出 INSERT 语句应该用 N'...' 标记为正确插入为 Unicode。

解决方案 正如@deroby 所说,这似乎是一个整理问题,将其更改为 Finnish_Swedish_100_CI_AS 似乎可以使事情按预期进行。

select * from #Test where Value like N'%%' COLLATE Finnish_Swedish_100_CI_AS

加上

会更有趣
INSERT INTO #Test VALUES (''); -- should be http://emojipedia.org/eyes/

您的第一个 SELECT 现在将 return 两个表情符号记录;即使它们看起来不对。原因是 </code> 和 <code> 都是无效的 varchar() 值。所以它们导致一些占位符被放入数据库(显示为 ??)。

现在,如果您执行插入 'properly' 并将数据作为正确的 Unicode 字符串插入,那么事情会好很多:

INSERT INTO #Test VALUES (N'');
INSERT INTO #Test VALUES (N'a');
INSERT INTO #Test VALUES (N'b');
INSERT INTO #Test VALUES (N'c');
INSERT INTO #Test VALUES (N''); -- should be http://emojipedia.org/eyes/
INSERT INTO #Test VALUES (N''); -- should be http://emojipedia.org/eyes/

select * from #Test -- returns everything
select * from #Test where Value like '%%' -- returns nothing (because it looks for the '??' placeholder
select * from #Test where Value like N'%%' -- returns just one line

PS:这就是它在我的 SQL2012 上的工作方式 (Latin1_General_BIN)。

Why does the the second select match all rows in the table?

那个我也解释不了;对我来说不是。所以我猜这是一个整理问题,这些表情符号都被认为是平等的。

确实,在做测试

select * from #Test where Value like N'%%' COLLATE Finnish_Swedish_CI_AS
select * from #Test where Value like N'%%' COLLATE Latin1_General_BIN

说明需要到这里找原因。至于为什么,我也不知道。