2011-03-03 74 views
5

SQL Server中是否有任何方法可以确定代码页中的某个字符将代表什么内容,而无需实际创建该排序规则的测试数据库?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

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

有我见过处理转换两种可能的方法,一种是这里详细 http://www.codeguru.com/cpp/data/data-misc/values/article.php/c4571 和包括螺栓自定义转换程序到数据库,并使用,对转换。

另一个是构造由

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

与存储为代表的Unicode字符中的int的Unicode值分贝表使用nchar()或NCHAR本身

你的使用被转换校对SQL_Ukrainian_CP1251_CS_AS它是代码页1251(字符串中心的CP1251)。你可以在这里获取它的翻译表http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT

它是一个TSV所以在修剪掉原始数据的顶部之后应该相当干净地导入。

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

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