2011-03-03 118 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