SQL Server代码页和排序规则

Mar*_*ith 5 sql-server collation

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

例.如果我使用排序规则创建测试数据库,SQL_Ukrainian_CP1251_CS_AS然后CHAR(255)返回?.

但是,如果我在具有SQL_Latin1_General_CP1_CS_AS排序规则的数据库上尝试以下操作

SELECT CHAR(255) COLLATE SQL_Ukrainian_CP1251_CS_AS
Run Code Online (Sandbox Code Playgroud)

它回来了 y

SELECT CHAR(255)
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ith 7

其实我现在已经找到了问题的答案.有点笨拙,但除非有更好的方法,否则做好工作?

SET NOCOUNT ON;

CREATE TABLE #Collations
(
     code TINYINT PRIMARY KEY
);

WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),   --2
        E02(N) AS (SELECT 1 FROM E00 a, E00 b), --4
        E04(N) AS (SELECT 1 FROM E02 a, E02 b), --16
        E08(N) AS (SELECT 1 FROM E04 a, E04 b) --256
INSERT INTO #Collations
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1
FROM E08    

DECLARE @AlterScript NVARCHAR(MAX) = ''

SELECT @AlterScript = @AlterScript + ' 
RAISERROR(''Processing' + name + ''',0,1) WITH NOWAIT;
ALTER TABLE #Collations ADD ' + name + ' CHAR(1) COLLATE ' + name + ';
EXEC(''UPDATE #Collations SET ' + name + '=CAST(code AS BINARY(1))'');
EXEC(''UPDATE #Collations SET ' + name + '=NULL WHERE ASCII(' + name + ') <> code'');
'
FROM   sys.fn_helpcollations()
WHERE  name LIKE '%CS_AS'
       AND name NOT IN    /*Unicode Only Collations*/
                        ( 'Assamese_100_CS_AS', 'Bengali_100_CS_AS',
                         'Divehi_90_CS_AS', 'Divehi_100_CS_AS' ,
                         'Indic_General_90_CS_AS', 'Indic_General_100_CS_AS',
                             'Khmer_100_CS_AS', 'Lao_100_CS_AS',
                         'Maltese_100_CS_AS', 'Maori_100_CS_AS',
                         'Nepali_100_CS_AS', 'Pashto_100_CS_AS',
                         'Syriac_90_CS_AS', 'Syriac_100_CS_AS',
                         'Tibetan_100_CS_AS' )


EXEC (@AlterScript)

SELECT * FROM #Collations

DROP TABLE #Collations
Run Code Online (Sandbox Code Playgroud)


Rob*_*obb 2

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

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

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

[CodePage], [ANSI Value], [UnicodeValue]
Run Code Online (Sandbox Code Playgroud)

unicode 值存储为表示要使用的 unicode 字符的 intnchar()或 nchar 本身

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

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

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