SQL函数替换字符串中的多个字符

时间:2012-07-26 13:20:49

标签: string sql-server-2008 replace while-loop

我正在编写一个SQL Server 2008用户定义函数来将字符串的字符替换为另一个字符。我认为下面的代码应该有效,但事实并非如此。它似乎没有正确更新@input的变量。

知道如何解决这个问题吗?

 DECLARE @Input AS VarChar(1000)
 DECLARE @i AS TinyInt
 DECLARE @Substring AS VarChar(1000)
 DECLARE @Prestring  AS VarChar(1000)
 DECLARE @Poststring  AS VarChar(1000)

 Select @Input='ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789',
        @i = 1

 WHILE @i <= LEN(@Input) 
 BEGIN
    SELECT @Prestring = SUBSTRING(@Input,-1,@i)
    SELECT @Poststring = SUBSTRING(@Input,@i+1,LEN(@Input))    

    SELECT @Substring =  replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace
(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace
(SUBSTRING(@Input,@i,1), 'A', 'N'),'B', 'O'), 'C', 'P'), 'D', 'Q'), 'E', 'R'), 'F', 'S'), 'G', 'T'), 'H', 'U'), 'I', 'V'), 'J', 'W'), 'K', 'X'), 'L', 'Y'), 'M', 'Z'), 'N', 'A'), '0', 'B'), 'P', 'C')
, 'Q', 'D'),'R', 'E'),'S', 'E'),'T', 'E'),'U', 'F'),'V', 'G'),'W', 'H'),'X', 'I'),'Y', 'J'), '1', '9'),'2','8'),'3','7'),'4','6'),'5','5'),'6','4'),'7','3'),'8','2'),'9','1'),' ','')

    SELECT @Input = @Prestring + @Substring + @Poststring
    SELECT @i = @i + 1

    PRINT 'Prestring= ' + @Prestring PRINT 'SUBSTRING= ' + @Substring PRINT 'PostString= '     + @Poststring PRINT 'Total String: ' + @Prestring + ' + ' + @Substring + ' + ' + @Poststringenter code here

    PRINT 'END'

 END

Output:
Prestring= 
SUBSTRING= A
PostString= BCDEFGHIJKLMNOPQRSTUVWXYZ123456789
Total String:  + A + BCDEFGHIJKLMNOPQRSTUVWXYZ123456789
1
END

Prestring= A
SUBSTRING= O
PostString= CDEFGHIJKLMNOPQRSTUVWXYZ123456789
Total String: A + O + CDEFGHIJKLMNOPQRSTUVWXYZ123456789
2
END

Prestring= AO
SUBSTRING= C
PostString= DEFGHIJKLMNOPQRSTUVWXYZ123456789
Total String: AO + C + DEFGHIJKLMNOPQRSTUVWXYZ123456789
3
END

Prestring= AOC
SUBSTRING= D
PostString= EFGHIJKLMNOPQRSTUVWXYZ123456789
Total String: AOC + D + EFGHIJKLMNOPQRSTUVWXYZ123456789
4
END

......

5 个答案:

答案 0 :(得分:1)

这是双向工作的另一种方式:

declare @input nvarchar(max) = N'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'
    , @output nvarchar(max) = N''
    , @i int = 1

while @i <= len(@input) begin
    declare @unicode int = unicode(substring(@input, @i, 1))
    select @output = @output + nchar(
            case
                when @unicode between 65 and 77 then @unicode + 13
                when @unicode between 78 and 90 then @unicode - 13
                when @unicode between 49 and 57 then 106 - @unicode
                else @unicode
            end
        )
        , @i = @i + 1
end

select @input as VerySimpleCipher
union all
select @output

如果您在做更多条件,我可能会使用表变量作为地图。您可能希望添加小写字母,零,空值等的处理。此外,我会提醒您不要将此作为某种类型的密码用于除了娱乐之外的其他任何内容。

答案 1 :(得分:0)

重新检查您的转化。

您转换C-> P,然后稍后将其更新为P-&gt; C.

每次替换都是从最里面的调用开始的。你应该把它们分解成一个函数,并在它第一次匹配时返回。

答案 2 :(得分:0)

这应该让你开始......

-- A should return N
select dbo.ConvertChars('A');
-- B should return O
select dbo.ConvertChars('B');


--create function dbo.ConvertChars(@input char(1))
alter function dbo.ConvertChars(@input char(1))
returns char(1)
begin


    IF @input='A' return 'N';   
    IF @input='B' return 'O';


    return '';

end

答案 3 :(得分:0)

我没有对此进行过测试,但它会从上面的代码开始。至少应该让你知道如何做到这一点。

create function dbo.ConvertCharString(@input varchar(1000))
returns varchar(1000)
begin
declare @id int
declare @len int
declare @c vhar(1)
declare @return varchar(1000)
        SET @idx = 0
        SELECT @idx = CHARINDEX(@delimiter, @str)
        SELECT @len = len(@input)

        -- loop through delimiter sep. list until no more comma's found i.e. charindex returns 0
        while  (@idx <= @len)
        begin
            set @c = substring(@input, @idx, 1)
            select @return = @return + dbo.ConvertChars(@c)
            select @idx = @idx-1
        end


end

答案 4 :(得分:0)

请参阅下面的答案!多亏了所有人,这比我应该做的更难!

创建函数dbo.Translate(@Input varchar(1000))     退货变量(1000)     BEGIN

DECLARE @i AS Int
Declare @SingleChar_Offset AS VarChar(1000)
Declare @Output AS VarChar(1000)
DECLARE @Unicode_Offset AS Int
DECLARE @UnicodeChar AS Int


SELECT @i = 1
Select @Output = ''


WHILE @i <= LEN(@Input) 
BEGIN
  Select @UnicodeChar = unicode(substring(@Input, @i, 1))

    IF @UnicodeChar <=52
      BEGIN
            Select @Unicode_Offset = @UnicodeChar+5
      END
  ELSE IF @UnicodeChar >52 AND @UnicodeChar <=57
      BEGIN
            Select @Unicode_Offset = @UnicodeChar-5
      END

  IF @UnicodeChar >= 65 AND @UnicodeChar <=77
      BEGIN
            Select @Unicode_Offset = @UnicodeChar+13
      END
  ELSE IF @UnicodeChar > 77
      BEGIN
            Select @Unicode_Offset = @UnicodeChar-13
      END

  Select @SingleChar_Offset = CHAR(@Unicode_Offset)
  SELECT @i = @i + 1   
  --PRINT @SingleChar_Offset
     Select @Output = @Output + @SingleChar_Offset
-- print 'END
-- '

END

--PRINT @Output

RETURN @Output

END