SQL 服务器在 Arabic_CI_AS 排序规则中没有区分 'ь' 和 'ي'

SQL Server not difference between 'ی' and 'ي' in Arabic_CI_AS collation

我正在使用 ASCII 函数来获取两个字符的等价 ASCII 码,但我很惊讶地发现 'ي' 和 '̶' 之间没有区别,有人可以帮助我吗?

SELECT ASCII('ي'), ASCII('ی')

这是一个限制 ASCII 功能。根据 documentation, ASCII:

Returns the ASCII code value of the leftmost character of a character expression.

但是,你问题中的字符是由多个字节组成的。看来ASCII只能读取一个字节。

当您将这些字符用作不带 N 前缀的字符串文字时,它们将被视为单字节字符。以下查询显示 SQL 服务器在 Arabic_CI_AS 归类中将这些字符正确标记为多字节时不将它们视为相等:

SELECT CASE WHEN 'ي' COLLATE Arabic_CI_AS <> 'ی' COLLATE Arabic_CI_AS
THEN 1 ELSE 0 END AS are_different_ascii,
CASE WHEN N'ي' COLLATE Arabic_CI_AS <> N'ی' COLLATE Arabic_CI_AS
THEN 1 ELSE 0 END AS are_different_unicode

以下查询显示组成字符的字节:

SELECT CAST(N'ي' COLLATE Arabic_CI_AS as varbinary(4)),
CAST(N'ی' COLLATE Arabic_CI_AS as varbinary(4)),
CAST('ي' COLLATE Arabic_CI_AS as varbinary(4)),
CAST('ی' COLLATE Arabic_CI_AS as varbinary(4))

但是,即使您将字符标记为 unicode,ASCII 函数也会 returns 相同的值,因为它只能读取一个字节:

SELECT ASCII(N'ي' COLLATE Arabic_CI_AS) , ASCII(N'ی' COLLATE Arabic_CI_AS)

编辑 作为 TT。指出,这些字符在 ASCII 码 table.

中没有条目

因为您的字符不是 Unicode,所以您必须使用 UNICODE() 函数而不是 ASCII()

SELECT ASCII('ي'), ASCII('ی')

将得到:237237

但是

SELECT UNICODE(N'ي'), UNICODE(N'ی')

将得到:16101740

试试这个

SELECT UNICODE(N'ي'), UNICODE(N'ی')

如果您想使用 Ascii,则使用适当的整理的另一种解决方案

Arabic_CS_AS_KS

结果 ى = 236 和 ي= 237

当我们有以下脚本时,故事会变得有趣:

SELECT ASCII('ك'), ASCII('ک');

SELECT
CASE
    WHEN 'ك' COLLATE Arabic_CI_AS <> 'ک' COLLATE Arabic_CI_AS
    THEN 1 ELSE 0 END AS are_different_ascii,
CASE WHEN N'ك' COLLATE Arabic_CI_AS <> N'ک' COLLATE Arabic_CI_AS
    THEN 1 ELSE 0 END AS are_different_unicode;

ک 和 ك 这个字母好像是个例外!

不是吗?