NVARCHAR 列上的相等查询在 SQL Server 2012 中产生多个结果

swa*_*eck 8 postgresql sql-server

我正在将一个宠物项目从 PostgreSQL (9.2.2) 迁移到 SQL Server (2012 Standard)。

在查询 unicode 单词时,我注意到一个有趣的现象。鉴于定义:

CREATE TABLE [word](
    [id] [int] IDENTITY(0,1) NOT NULL,
    [value] [nvarchar](255) NULL    
 );
Run Code Online (Sandbox Code Playgroud)

和数据:

insert into word (value) values (N'????');
insert into word  (value) values (N'???');
insert into word  (value) values (N'???');
insert into word (value) values  (N'???');
insert into word (value) values  (N'???');
insert into word (value) values  (N'???');
insert into word (value) values  (N'???');
insert into word (value) values  (N'???');

insert into word  (value) values (N'??????');
insert into word  (value) values (N'?????');
insert into word (value) values  (N'?????');
insert into word  (value) values (N'?????');
Run Code Online (Sandbox Code Playgroud)

对特定单词的查询将返回接近匹配项。例如:

select * from word where value = N'???'
Run Code Online (Sandbox Code Playgroud)

返回:

id  value
102137  ????
102141  ???
102142  ???
102143  ???
102144  ???
102145  ???
102146  ???
102147  ???
Run Code Online (Sandbox Code Playgroud)

http://sqlfiddle.com/#!6/1ab66/1

但是,PostgreSQL 中的相同模式仅返回完全匹配。我怎样才能让 SQL Server 做同样的事情?

(PostgreSQL 小提琴链接):http ://sqlfiddle.com/#!12/ c57a6/1

我有一种明显的感觉,我错过了一些东西,但我不太能弄清楚它是什么。

数据库归类SQL_Latin1_General_CP1_CI_AS(这也是服务器的归类)在本地安装上。

Mar*_*ith 8

排序规则决定了比较语义。

如果我尝试

CREATE TABLE [word](
    [id] [int] IDENTITY(0,1) NOT NULL,
    [value] [nvarchar](255) COLLATE Latin1_General_100_CI_AS NULL    
 );
Run Code Online (Sandbox Code Playgroud)

它只返回???.

将后缀更改为AIfor 重音不敏感???也返回。

在我的安装中,我尝试了所有排序规则并1526返回1(大概ASBIN排序规则),1264返回 2 行(大概AI)并1095返回8.

快速浏览这最后一组看起来包括所有SQL排序规则和90排序规则,而所有排序规则和排序规则都100在前 2 组中,所以我认为这是 2008 批排序规则中已修复的一些问题。(请参阅SQL Server 2008 排序规则中的新增功能

自己尝试的脚本

DECLARE @Results TABLE
(
Count INT,
Collation SYSNAME
)

SET NOCOUNT ON;
DECLARE @N SYSNAME;
DECLARE @C1 AS CURSOR;
SET @C1 = CURSOR FAST_FORWARD FOR 
SELECT name
FROM sys.fn_helpcollations();
OPEN @C1;
FETCH NEXT FROM @C1 INTO @N ;
WHILE @@FETCH_STATUS = 0
BEGIN
  INSERT @Results
  EXEC('SELECT COUNT(*), ''' + @N + ''' from word where value = N''???'' COLLATE ' + @N)
  FETCH NEXT FROM @C1 INTO @N ;
END

SELECT *
FROM @Results
ORDER BY Count DESC
Run Code Online (Sandbox Code Playgroud)