SQL Server 代码页和排序规则

问题描述 投票:0回答:2

SQL Server 中是否有任何方法可以确定代码页中的字符代表什么,而无需实际创建该排序规则的测试数据库?

示例。如果我使用排序规则

SQL_Ukrainian_CP1251_CS_AS
创建测试数据库,然后执行
CHAR(255)
,它将返回
я

如果我在具有

SQL_Latin1_General_CP1_CS_AS
排序规则的数据库上尝试以下操作

SELECT CHAR(255) COLLATE SQL_Ukrainian_CP1251_CS_AS

它返回

y

SELECT CHAR(255)

返回

ÿ
,因此它显然首先通过数据库的默认排序规则,然后尝试找到与显式排序规则中最接近的等效项。这可以避免吗?

sql-server collation
2个回答
8
投票

实际上有一种相当直接的方法可以做到这一点

SELECT CONCAT(CAST(255 AS BINARY(1)), '' COLLATE SQL_Ukrainian_CP1251_CS_AS)

因此,基于此方法,SQL Server 2022+ 兼容脚本可为正在使用的所有 16 个非 utf8 代码页返回从

0x01
0xFF
的 255 个值 (DB Fiddle)。

DECLARE @DynSQL NVARCHAR(MAX);

WITH DistinctCodePage AS
(
SELECT CodePage = CAST(COLLATIONPROPERTY(name, 'CodePage') AS INT), 
       ExampleCollation = MAX(name)
FROM sys.fn_helpcollations()
WHERE COLLATIONPROPERTY(name, 'CodePage') NOT IN (0 /*Exclude Unicode only collations*/, 65001 /*Exclude utf8 collations*/)
GROUP BY COLLATIONPROPERTY(name, 'CodePage')
)
SELECT  @DynSQL = 'SELECT  value,' + 
STRING_AGG(CONVERT(NVARCHAR(MAX), quotename(CodePage) + ' = CONCAT(CAST(value AS binary(1)), SPACE(0) COLLATE ' + ExampleCollation + ')' ), ',') + 
'
FROM generate_series(1,255)
ORDER BY value desc'
FROM   DistinctCodePage;

EXEC (@DynSQL);

2
投票

虽然 MS SQL 同时支持代码页和 Unicode,但它不提供任何在两者之间进行转换的函数,因此弄清楚不同代码页中的值代表什么字符是一件很困难的事情。

我见过两种可能的方法来处理转换,其中一种详细信息请参见此处 http://www.codeguru.com/cpp/data/data-misc/values/article.php/c4571 并涉及将自定义转换程序连接到数据库并使用它进行转换。

另一种是构建一个数据库表,其中包括

[CodePage], [ANSI Value], [UnicodeValue]

将 unicode 值存储为表示要使用

nchar()
转换的 unicode 字符的 int 或 nchar 本身

您使用的排序规则

SQL_Ukrainian_CP1251_CS_AS
是代码页1251(从字符串中心开始的CP1251)。您可以在此处获取其翻译表http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT

它是一个 TSV,因此在修剪顶部后,原始数据应该相当干净地导入。

就我个人而言,我更倾向于后者而不是前者,特别是对于生产服务器,因为前者可能会带来不稳定。

© www.soinside.com 2019 - 2024. All rights reserved.