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等效的拉丁排序规则,但不适用于旧版本,即适用于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;