Sql server SQL Server 2008 R2日语(NVARCHAR)字符串比较出错? 问题

Sql server SQL Server 2008 R2日语(NVARCHAR)字符串比较出错? 问题,sql-server,unicode,sql-server-2008-r2,Sql Server,Unicode,Sql Server 2008 R2,在SQL Server 2008 R2上运行以下查询时,两个不同的日文unicode字符串被视为相等: SELECT CASE WHEN N'食料' = N'食料ㇰ ㇱ ㇲ ㇳ' THEN 1 ELSE 0 END; --result: 1 我知道汉字后面的假名是半宽的,但由于没有类似的全宽假名,我不认为宽度敏感或假名敏感有什么关系。但是,如果将假名替换为全宽版本,则比较的行为与预期相同: SELECT CASE

在SQL Server 2008 R2上运行以下查询时,两个不同的日文unicode字符串被视为相等:

SELECT
    CASE
        WHEN N'食料' = N'食料ㇰ ㇱ ㇲ ㇳ'
            THEN 1
        ELSE 0
    END;

--result: 1
我知道汉字后面的假名是半宽的,但由于没有类似的全宽假名,我不认为宽度敏感或假名敏感有什么关系。但是,如果将假名替换为全宽版本,则比较的行为与预期相同:

SELECT
    CASE
        WHEN N'食料' = N'食料ク シ ス ト'
            THEN 1
        ELSE 0
    END;

--result: 0
尝试的解决方案 这让我想到这个问题可能与我的排序规则有关,即
SQL\u Latin1\u General\u CP1\u CI\u AS

首先,我尝试了
Latin1\u General\u CI\u AS
,以防这是SQL Unicode比较的一个怪癖,但这并没有解决问题

然后,我想我会使用尽可能严格的排序规则(所有敏感度都是),但其他排序规则,包括
Latin1\u General\u CS\u AS\u KS\u WS
Japanese\u Unicode\u CS\u AS\u KS\u WS
在使用半宽尾随假名时并没有改变结果(都正确地识别了与全宽尾随假名的差异)

为了验证字符串在字节级别上是否不同,我在删除字符串的
N
(nvarchar)指定后使用半宽度尾随假名运行了查询,并验证了它是否返回了
0
的预期结果

问题 这是怎么回事?我只是没有尝试正确的排序吗?这是SQL Server 2008 R2中的错误吗?关于日文Unicode有什么我不知道的地方吗?为什么半宽度尾随假名的存在不会使这些字符串有所不同


PS我不懂日语,所以如果我把我对字符的描述弄错了,我道歉。

长短不一的是,在大量排序中,第一个示例中的字符等于一个空格

在进行字符串比较时,SQL server会消除字符串末尾的尾随空格(一个例外是使用类似于的
时,但在这里不这样做)

例如,在字符串
N'食料ㇰ ㇱ ㇲ ㇳ',在
被视为尾随空格,并在进行字符串比较时删除

要使用给定的排序规则进行快速检查,可以运行以下查询:

WITH 
    Vals AS (SELECT FullString, StringNum FROM (VALUES (N'食料', 1), (N'食料ㇰ ㇱ ㇲ ㇳ', 2), (N'食料ク シ ス ト', 3)) AS T(FullString, StringNum)),
    CTE AS -- A recursive CTE to split the characters up in your strings and check the individual characters. 
    (
        SELECT FullString,
                StringNum,
                IndividualCharacter = SUBSTRING(FullString, 1, 1),
                UnicodeNumber = UNICODE(SUBSTRING(FullString, 1, 1)),
                UnicodeBinary = CAST(SUBSTRING(FullString, 1, 1) AS VARBINARY(2)),
                CharPosition = 1
        FROM Vals
        UNION ALL 
        SELECT V.FullString,
                V.StringNum,
                IndividualCharacter = SUBSTRING(V.FullString, C.CharPosition + 1, 1),
                UnicodeNumber = UNICODE(SUBSTRING(V.FullString, C.CharPosition + 1, 1)),
                UnicodeBinary = CAST(SUBSTRING(V.FullString, C.CharPosition + 1, 1) AS VARBINARY(2)),
                CharPosition = C.CharPosition + 1
        FROM Vals AS V
        JOIN CTE AS C
            ON C.StringNum = V.StringNum
        WHERE C.CharPosition + 1 <= LEN(V.FullString)
    )
SELECT C.*,
       CharacterEqualToSpace = CASE WHEN NCHAR(C.UnicodeNumber) COLLATE Japanese_Unicode_CS_AS_KS_WS = NCHAR(32) THEN 1 ELSE 0 END,
       FullStringWithoutSpace = SUBSTRING(C.FullString, 1, (SELECT MAX(CharPosition) FROM CTE AS C2 WHERE C2.StringNum = C.StringNum AND NCHAR(C2.UnicodeNumber) COLLATE Japanese_Unicode_CS_AS_KS_WS != NCHAR(32))) -- Eliminate white space on the end for this collation, with a substring ending at the last character that does not equal white space.
FROM CTE AS C
ORDER BY StringNum, CharPosition;
WITH T(N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) AS A(B)), -- 16
    T2(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 FROM T AS A CROSS JOIN T AS B CROSS JOIN T AS C CROSS JOIN T) -- 16^4.
SELECT WhiteSpaceCharacters = NCHAR(N)
FROM T2
WHERE NCHAR(N) COLLATE Japanese_Unicode_CS_AS_KS_WS = NCHAR(32);