Sql server SQL Server代码页和排序规则

Sql server SQL Server代码页和排序规则,sql-server,collation,Sql Server,Collation,SQL Server中是否有任何方法可以在不实际创建排序规则的测试数据库的情况下确定代码页中的字符代表什么 例如。如果我使用排序规则SQL_Ukrainian_CP1251_CS_AS创建一个测试数据库,然后执行CHAR255,它将返回 但是,如果我在一个以SQL\u Latin1\u General\u CP1\u CS\u作为排序规则的数据库上尝试以下操作 SELECT CHAR(255) COLLATE SQL_Ukrainian_CP1251_CS_AS 它返回y 返回ÿ,因此它显然

SQL Server中是否有任何方法可以在不实际创建排序规则的测试数据库的情况下确定代码页中的字符代表什么

例如。如果我使用排序规则SQL_Ukrainian_CP1251_CS_AS创建一个测试数据库,然后执行CHAR255,它将返回

但是,如果我在一个以SQL\u Latin1\u General\u CP1\u CS\u作为排序规则的数据库上尝试以下操作

SELECT CHAR(255) COLLATE SQL_Ukrainian_CP1251_CS_AS
它返回y


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

虽然MS SQL同时支持代码页和Unicode,但毫无帮助,它不提供任何函数在这两者之间进行转换,因此,在不同的代码页中计算值代表的字符是一个问题

我见过两种可能的方法来处理转换,其中一种在这里详细介绍 包括将自定义转换程序连接到数据库上,并将其用于转换

另一种是构造一个数据库表,由

[CodePage], [ANSI Value], [UnicodeValue]
将unicode值存储为表示要使用ncharor转换的unicode字符的int或nchar本身

您可以使用排序规则SQL_Ukrainian_CP1251_CS_AS,该排序规则位于字符串中心的代码页1251 CP1251。你可以在这里找到它的翻译表

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


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

事实上,我现在已经找到了问题的答案。有点笨重,但除非有更好的方法,否则你能胜任吗

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
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