sql-server – SQL Server 2008 R2中的Unicode规范化

@I在表格中有一行,其中包含以下文字“Urbański,Mariusz”.字符“ń”的十六进制表示是“6e cc 81”.因此,它存储在分解Unicode规范化表单中.

当我使用如下的查询“……其中Identification =N’Urbański,Mariusz’”和字符“ń”匹配分解形式(“6e cc 81”)时,查询返回预期记录.

如果我使用组合Unicode规范化表单(“ń”=“c5 84”)运行完全相同的查询,我得不到任何结果.

我也试过“选择1N’Urbański,Mariusz’=N’Urbański,Mariusz’,”我使用“ń”的2种变体,它总是返回true.

有没有办法让SQL Server将2个值视为相等?

以下是我的数据库配置由Rhys Jones请求

Database Collation : "Danish_Norwegian_CI_AS"
Column1 : IdRightsHolderSourceIdentification = NULL  
Column2 : VersionInfo = NULL  
Column3 : Source = "Danish_Norwegian_CI_AS"
Column4 : Identification = "SQL_Latin1_General_CP437_BIN"
Column5 : RightsHolder = NULL

正如Rhys Jones非常好地猜测的那样,有问题的专栏是第4列,它有二进制整理(这就是BIN到底意味着什么?).非常感谢您的帮助.

最佳答案 我可以从你的问题中看到你理解Unicode,所以我想你缺少的是在SQL Server中有一种称为整理的东西.这就决定了SQL Server如何比较值.我已经整理了一个脚本来演示两种形式的名称之间的各种成功和不成功的比较.我当前使用的SQL Server设置使用Latin1_General_CI_AS,其中名称的两种形式都相等.我尝试了一些东西,但除非我使用二进制整理,否则我不能使它们不相等.我有兴趣了解您的服务器和数据库排序规则,并查看表的表定义(包括排序规则).

希望这可以帮助,

里斯

-- UTF8 character list -- http://www.fileformat.info/info/charset/UTF-8/list.htm?
--    n - LATIN SMALL LETTER N (U+006E) 6e 
--    ́    - COMBINING ACUTE ACCENT (U+0301) cc81 
--    ń - LATIN SMALL LETTER N WITH ACUTE (U+0144) c584 

create table dbo.MyTable (id int not null, name nvarchar(100) collate Latin1_General_CI_AS not null)

declare @a nvarchar(100); set @a = N'Urba' + nchar(0x0144) + N'ski, Mariusz'
declare @b nvarchar(100); set @b = N'Urba' + nchar(0x6e) + nchar(0x0301) + N'ski, Mariusz'

insert dbo.MyTable values (1, @a)
insert dbo.MyTable values (2, @b)

-- Display server, database and column collations
select
    SERVERPROPERTY(N'Collation') as [server_collation],
    DATABASEPROPERTYEX(DB_NAME(), N'Collation') as [database_default_collation],
    c.collation_name as [column_collation]
from
    sys.objects t join sys.columns c on c.object_id = t.object_id
where 
    t.object_id = object_id('dbo.MyTable') and c.name = 'name'

-- Test with Latin1_General_CI_AS
select id, name from dbo.MyTable where name collate Latin1_General_CI_AS = @a collate Latin1_General_CI_AS

-- Test with French_CI_AS
select id, name from dbo.MyTable where name collate French_CI_AS = @a collate French_CI_AS

-- Test with Latin1_General_BIN2
select id, name from dbo.MyTable where name collate Latin1_General_BIN2 = @a collate Latin1_General_BIN2
点赞