2012-04-09 10 views
0

SQL Server 2008 R2で実行しています。以前にレガシーシステムで使用されていたロケール言語文字に一部の英字を置き換える必要がありました。このためSQL Server 2008 R2の文字マッピング/検索と文字単位の置換

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

は今、私が意味している交換するネステッド使用しないようにしたい、私はおそらくT-SQLで置き換える機能を使用することになりますが、私の練習では、我々は、例えば文字ずつ交換します私は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は文字列操作で非常に制限されています... –

+0

CLRは本番サーバーではオプションではありません。サーバー上の重い開発を制限する方法で実装されています。私が今言っているように、仕事はしていますが、それはかなり遅いです。 –

答えて

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 

は、それは非常に似ていますが、私はセットで作業する場合、SQL Serverがよりよく機能することはなくelse ifチェックの非常に大規模なシリーズより願っています。 @MappingCharactersが本当のテーブルであるかどうかわからない場合は、これがうまくいくかどうかはわかりません。

+2

テーブルを 'DECLARE @MappingCharacters TABLE(InputCharacter NCHAR(1)COLLATE SQL_Latin1_General_CP1_CS_AS PRIMARY KEY、OutputChar NCHAR(1))'として宣言すると、インデックスシークを使用できます。 –

+0

@MartinSmithそれは最高です。私はそれを認識しませんでした。私は編集をするつもりです。 –

関連する問題