SQL Server代码页和排序规则

时间:2011-03-03 12:35:51

标签: 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

返回y

SELECT CHAR(255)

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

虽然MS SQL同时支持代码页和Unicode,但它没有提供任何函数来在两者之间进行转换,因此找出不同代码页中的值所表示的字符是猪。

我见过两种可能的方法来处理转换,其中一种方法在此详述 http://www.codeguru.com/cpp/data/data-misc/values/article.php/c4571 并涉及将自定义转换程序用螺栓连接到数据库并将其用于转换。

另一种是构建一个由

组成的db表
[CodePage], [ANSI Value], [UnicodeValue]

将unicode值存储为int,表示要使用nchar()转换的unicode字符或nchar本身

您使用的是排序规则SQL_Ukrainian_CP1251_CS_AS,即代码页1251(来自字符串中心的CP1251)。您可以在此处http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT

获取其翻译表

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

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