2014-10-28 87 views
1

在比较两个字符串时,SQL Server 2008似乎删除了一些unicode字符。请看下面的表格:SQL Server 2008和Unicode字符比较

CREATE TABLE [dbo].[Test](
[text] [nvarchar](50) NOT NULL, 
    CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
    (
    [text] ASC 
)) 

现在,如果我插入一些行Unicode字符:

insert into Test values(N'it᧠') 
insert into Test values(N'it') 

我得到一个唯一约束的例外,即使值是不同的。我在这里使用默认的数据库排序规则,即SQL_Latin1_General_CP1_CI_AS。

Violation of PRIMARY KEY constraint 'PK_Test'. Cannot insert duplicate key in object 'dbo.Test'. 

注意,这并不会发生所有Unicode字符,但仅限于一些字符,但我一直没能找出其中的unicode范围究竟是有问题的。例如,dingbat 0x2757(❗)在比较中被移除,但是0x2764(♥)不是。我想这与0x2757来自一个更新的unicode标准有关。

所以问题是,是否有任何方法使SQL Server 2008与这些字符一起工作,或者,我是否可以通过编程方式检测它们(在C#中,通过unicode范围或某些类型)并事先删除它们?

+0

检查了这一点http://stackoverflow.com/questions/4144767/unicode-characters-in-sql-table – Bayeni 2014-10-28 08:16:08

+0

你应该设置您的字段类型为'nvarchar' – 2014-10-28 08:20:34

+0

@Bayeni,并不真正有帮助。我正在使用nvarchar和N前缀。 unicode值正确显示在表中,问题在于比较。 – 2014-10-28 08:22:30

回答

1

好了,所以多一点挖表明这几乎可以肯定是由于新的角色,因为这也与SQL服务器工作2008等效拉丁整理,但不是旧版本,即与Latin1_General_100_CI_AS工作,但不能与Latin1_General_CI_AS 。为了得到归类的完整列表是正确地比较这些字符串我用:

IF OBJECT_ID('Tempdb..#T') IS NOT NULL 
    DROP TABLE #T; 
IF OBJECT_ID('Tempdb..#V') IS NOT NULL 
    DROP TABLE #V; 

CREATE TABLE #V (A NVARCHAR(50), B NVARCHAR(50)); 
INSERT #V (A, B) VALUES (N'it᧠', N'it'); 

CREATE TABLE #T (Collation VARCHAR(500), Match BIT); 

DECLARE @SQL NVARCHAR(MAX) = (SELECT N'INSERT #T (Collation, Match) 
             SELECT ''' + Name + ''', CASE WHEN A = B COLLATE ' + name + ' THEN 1 ELSE 0 END 
             FROM #V;' 
           FROM sys.fn_helpcollations() 
           FOR XML PATH(''), TYPE 
          ).value('.', 'NVARCHAR(MAX)'); 

EXECUTE sp_executesql @SQL; 

SELECT * 
FROM #T 
WHERE Match = 0;