0

我正在编写一个 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

......
4

5 回答 5

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

如果您要执行更多条件,我可能会使用表变量作为地图。您可能想要添加对小写字母、零、空值等的处理。此外,我会警告不要将其用作某种类型的密码,而不是为了好玩。

于 2012-07-26T14:45:21.187 回答
0

重新检查您的转化。

您转换 C->P,然后稍后替换将其更新为 P->C。

每个替换都是从最里面的调用开始的。您应该将它们分解为一个函数,并在它第一次匹配某些内容时返回。

于 2012-07-26T13:35:13.103 回答
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
于 2012-07-26T13:36:50.150 回答
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
于 2012-07-26T13:58:03.947 回答
0

请看下面我的答案!多亏了所有人,这对我来说比应该的要难!

创建函数 dbo.Translate(@Input varchar(1000)) RETURNS VARCHAR (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
于 2012-07-26T17:07:34.873 回答