SQL Server 2008和Unicode字符比较

本文关键字:字符 比较 Unicode Server 2008 SQL | 更新日期: 2023-09-27 18:28:01

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范围或类似的方法)并提前删除它们?

SQL Server 2008和Unicode字符比较

好的,更多的挖掘表明,这几乎肯定是由于更新的字符,因为这也适用于sql server 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;