2012-04-09 43 views
0

我在SQL Server 2008 R2上運行,我們在這裏有一個要求,我需要創建替換某些英文字符到以前在舊系統中使用的本地語言字符。在SQL Server 2008 R2中字符映射/搜索和逐個字符替換

對於這一點,我可能會使用T-SQL的替換功能,但在我的實踐中,我們通過字符例如替換字符

'ASkjDe' 
A=char(XX) 
S=char(XX) 
k=char(XX) 
j=char(XX) 
D=char(XX) 
e=char(XX) 

現在,我想避免使用嵌套替換,這意味着我必須做32個字符檢查。是否有這樣的功能,我可以通過它的價值清單?

我們已經有一個替代功能,但它的速度很慢,我們希望替換功能可以做得更好。下面是我們使用

CREATE FUNCTION [dbo].[ArabicToString] (@inString VARCHAR(MAX)) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    DECLARE @Vchar char(1), @Result NVARCHAR(MAX), @Flag BIT, @Position INT, @StrLength INT, @LChar CHAR, @HChar NCHAR 

    SET @Result = '' 
    SET @Position = 1 
    SET @StrLength = DATALENGTH(@inString) -- string length not going to change 
    SET @VChar = SUBSTRING(@inString, @Position, 1) 
    if ASCII(@Vchar) > 189 and ASCII(@Vchar) < 255 
    RETURN Rtrim(Ltrim(@inString)) 

    WHILE (@Position <= @StrLength) -- leave loop if bad character found 
    BEGIN 
     -- Reset holders 
     SET @LChar = SUBSTRING(@inString, @Position, 1) 
     Set @HChar = '' 

     if cast(@LChar as varbinary(1))=cast('*' as varbinary(1)) 
      Set @HChar = '*' 
     else if cast(@LChar as varbinary(1)) = cast('-' as varbinary(1)) 
      set @HChar = '-' 
     else if cast(@LChar as varbinary(1)) = cast('A' as varbinary(1)) 
      set @HChar = 'ء' 
     else if cast(@LChar as varbinary(1)) = cast('B' as varbinary(1)) 
      set @HChar='آ' 
     else if cast(@LChar as varbinary(1)) = cast('C' as varbinary(1)) 
      set @HChar='أ' 
     else if cast(@LChar as varbinary(1)) = cast('D' as varbinary(1)) 
      set @HChar='ؤ' 
     else if cast(@LChar as varbinary(1)) = cast('E' as varbinary(1)) 
      set @HChar='إ' 
     else if cast(@LChar as varbinary(1)) = cast('F' as varbinary(1)) 
      set @HChar ='ئ' 
     else if cast(@LChar as varbinary(1)) = cast('G' as varbinary(1)) 
      set @HChar='ا' 
     else if cast(@LChar as varbinary(1)) = cast('H' as varbinary(1)) 
      set @HChar='ب' 
     else if cast(@LChar as varbinary(1)) = cast('I' as varbinary(1)) 
      set @HChar='ة' 
     else if cast(@LChar as varbinary(1)) = cast('J' as varbinary(1)) 
      set @HChar='ت' 
     else if cast(@LChar as varbinary(1)) = cast('K' as varbinary(1)) 
      set @HChar='ث' 
     else if cast(@LChar as varbinary(1)) = cast('L' as varbinary(1)) 
      set @HChar='ج' 
     else if cast(@LChar as varbinary(1)) = cast('M' as varbinary(1)) 
      set @HChar='ح' 
     else if cast(@LChar as varbinary(1)) = cast('N' as varbinary(1)) 
      set @HChar='خ' 
     else if cast(@LChar as varbinary(1)) = cast('O' as varbinary(1)) 
      set @HChar='د' 
     else if cast(@LChar as varbinary(1)) = cast('P' as varbinary(1)) 
      set @HChar='ذ' 
     else if cast(@LChar as varbinary(1)) = cast('Q' as varbinary(1)) 
      set @HChar='ر' 
     else if cast(@LChar as varbinary(1)) = cast('R' as varbinary(1)) 
      set @HChar='ز' 
     else if cast(@LChar as varbinary(1)) = cast('S' as varbinary(1)) 
      set @HChar='س' 
     else if cast(@LChar as varbinary(1)) = cast('T' as varbinary(1)) 
      set @HChar='ش' 
     else if cast(@LChar as varbinary(1)) = cast('U' as varbinary(1)) 
      set @HChar='ص' 
     else if cast(@LChar as varbinary(1)) = cast('V' as varbinary(1)) 
      set @HChar='ض' 
     else if cast(@LChar as varbinary(1)) = cast('W' as varbinary(1)) 
      set @HChar='ط' 
     else if cast(@LChar as varbinary(1)) = cast('X' as varbinary(1)) 
      set @HChar='ظ' 
     else if cast(@LChar as varbinary(1)) = cast('Y' as varbinary(1)) 
      set @HChar='ع' 
     else if cast(@LChar as varbinary(1)) = cast('Z' as varbinary(1)) 
      set @HChar='غ' 
     else if cast(@LChar as varbinary(1)) = cast('a' as varbinary(1)) 
      set @HChar='ف' 
     else if cast(@LChar as varbinary(1)) = cast('b' as varbinary(1)) 
      set @HChar='ق' 
     else if cast(@LChar as varbinary(1)) = cast('c' as varbinary(1)) 
      set @HChar='ك' 
     else if cast(@LChar as varbinary(1)) = cast('d' as varbinary(1)) 
      set @HChar='ل'  
     else if cast(@LChar as varbinary(1)) = cast('e' as varbinary(1)) 
      set @HChar='م' 
     else if cast(@LChar as varbinary(1)) = cast('f' as varbinary(1)) 
      set @HChar='ن' 
     else if cast(@LChar as varbinary(1)) = cast('g' as varbinary(1)) 
      set @HChar='ه'  
     else if cast(@LChar as varbinary(1)) = cast('h' as varbinary(1)) 
      set @HChar='و' 
     else if cast(@LChar as varbinary(1)) = cast('i' as varbinary(1)) 
      set @HChar='ى' 
     else if cast(@LChar as varbinary(1)) = cast('j' as varbinary(1)) 
      set @HChar='ي'  


     else if cast(@LChar as varbinary(1)) = cast('v' as varbinary(1)) 
      set @HChar='ـ' 


     else if cast(@LChar as varbinary(1)) = cast('1' as varbinary(1)) 
      set @HChar='١' 
     else if cast(@LChar as varbinary(1)) = cast('2' as varbinary(1)) 
      set @HChar='٢'  
     else if cast(@LChar as varbinary(1)) = cast('3' as varbinary(1)) 
      set @HChar='٣' 
     else if cast(@LChar as varbinary(1)) = cast('4' as varbinary(1)) 
      set @HChar='٤' 
     else if cast(@LChar as varbinary(1)) = cast('5' as varbinary(1)) 
      set @HChar='٥' 
     else if cast(@LChar as varbinary(1)) = cast('6' as varbinary(1)) 
      set @HChar='٦'  
     else if cast(@LChar as varbinary(1)) = cast('7' as varbinary(1)) 
      set @HChar='٧' 
     else if cast(@LChar as varbinary(1)) = cast('8' as varbinary(1)) 
      set @HChar='٨' 
     else if cast(@LChar as varbinary(1)) = cast('9' as varbinary(1)) 
      set @HChar='٩'  
     else if cast(@LChar as varbinary(1)) = cast('0' as varbinary(1)) 
      set @HChar='٠' 

     else if @LChar='/' 
      set @HChar='\' 

     select @[email protected] + @HChar 

     -- Add one to position 
     SET @Position= @Position + 1 
    END 

    RETURN Rtrim(Ltrim(@Result)) 
END 

如果有人能提出一個不同的做法目前的功能,比替換功能,或者我們目前使用的我將不勝感激上述方法的東西甚至是其他。

+0

既可以使用你所擁有的,也可以檢查創建可以使用.NET字符串替換功能的SQL-CLR函數(用C#編寫)的可能性。 T-SQL在字符串操作方面非常有限...... – 2012-04-09 08:53:50

+0

在我們的生產服務器中,CLR不是一種選擇。它已經被用來限制服務器上任何繁重的開發。至於我目前所擁有的,正如我所說的那樣,但其工作非常緩慢。 – 2012-04-09 09:05:06

回答

2

這對你來說跑得快嗎? (我使用了SQL_Latin1_General_CP1_CS_AS的整理,你可能想改變它)。

ALTER FUNCTION [dbo].[ArabicToString] (@inString VARCHAR(MAX)) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    DECLARE @MappingCharacters TABLE 
    (
     InputCharacter NCHAR(1) COLLATE SQL_Latin1_General_CP1_CS_AS PRIMARY KEY, 
     OutputChar NCHAR(1) 
    ) 

    INSERT @MappingCharacters 
    VALUES 
     ('A', 'ء') 
     ,('B', 'آ') 
     ,('C', 'أ') 
     ,('D', 'ؤ') 
     ,('E', 'إ') 
     ,('F', 'ئ') 
     ,('G', 'ا') 
     ,('H', 'ب') 
     ,('I', 'ة') 
     ,('J', 'ت') 
     ,('K', 'ث') 
     ,('L', 'ج') 
     ,('M', 'ح') 
     ,('N', 'خ') 
     ,('O', 'د') 
     ,('P', 'ذ') 
     ,('Q', 'ر') 
     ,('R', 'ز') 
     ,('S', 'س') 
     ,('T', 'ش') 
     ,('U', 'ص') 
     ,('V', 'ض') 
     ,('W', 'ط') 
     ,('X', 'ظ') 
     ,('Y', 'ع') 
     ,('Z', 'غ') 
     ,('a', 'ف') 
     ,('b', 'ق') 
     ,('c', 'ك') 
     ,('d', 'ل') 
     ,('e', 'م') 
     ,('f', 'ن') 
     ,('g', 'ه') 
     ,('h', 'و') 
     ,('i', 'ى') 
     ,('j', 'ي') 
     ,('v', 'ـ') 
     ,('1', '١') 
     ,('2', '٢') 
     ,('3', '٣') 
     ,('4', '٤') 
     ,('5', '٥') 
     ,('6', '٦') 
     ,('7', '٧') 
     ,('8', '٨') 
     ,('9', '٩') 
     ,('0', '٠') 
     ,('/', '\') 

    DECLARE @Result NVARCHAR(MAX) = '' 
     , @Position INT = 1 
     , @StrLength INT = DATALENGTH(@inString) 

    DECLARE @Vchar char(1), @NextChar NCHAR(1) 

    SET @VChar = SUBSTRING(@inString, @Position, 1) 
    IF ASCII(@Vchar) > 189 and ASCII(@Vchar) < 255 
    RETURN Rtrim(Ltrim(@inString)) 

    WHILE (@Position <= @StrLength) -- leave loop if bad character found 
    BEGIN 
     -- Reset holders 
     SET @NextChar = SUBSTRING(@inString, @Position, 1) 

     SET @Result = @Result + ISNULL((SELECT OutputChar FROM @MappingCharacters MC WHERE InputCharacter = @NextChar COLLATE SQL_Latin1_General_CP1_CS_AS), @NextChar) 

     -- Add one to position 
     SET @Position= @Position + 1 
    END 

    RETURN Rtrim(Ltrim(@Result)) 
END 
GO 

這是非常相似的,但我希望這不是一個非常大的一系列else if檢查,有一組工作時,SQL Server將有更好的表現。我不確定這是否會更好,如果@MappingCharacters是一個真正的表。

+2

如果您將該表聲明爲DECLARE @MappingCharacters TABLE(InputCharacter NCHAR(1)COLLATE SQL_Latin1_General_CP1_CS_AS PRIMARY KEY,OutputChar NCHAR(1)),則可以使用索引查找。 – 2012-04-09 19:19:31

+0

@MartinSmith這真棒。我沒有意識到這一點。我會去做編輯。 – 2012-04-09 19:20:38