0

我正在对 SQL Server 表中的一些字符串进行“随机化”,以对它们进行原始加密。

我有一个嵌套的 SQL 替换函数大约 35 次(AZ,1-9),它基本上采用字母表和数字中的每个字母并将其替换为另一个字母或数字。其中的例子是

Replace(Replace(Replace('a', 'c'), 'b', 'a'), 'c', 'b')

我认为替换功能会通过像'abc'这样的字符串并替换所有内容并停止 - 'cab'。它没有!

似乎想再次更改一些字符导致'abc'->'cab'->'ccb'.

这很好,除非我有另一个名为“aac”的字符串,这可能会导致重复的字符串,并且我会失去对原始的可追溯性。

谁能解释我如何阻止 REPLACE() 部分返回我的字符串?

SELECT * INTO example_temp FROM example;
Update KAP_db.dbo.example_temp Set col1 = 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(
col1, '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'), 'O', 'A'), 'P', 'B'),
'Q', 'C'), 'R', 'D'),'S', 'E'),'T', 'E'),'U', 'E'),'V', 'F'),'W', 'G'),'X', 'H'),
'Y', 'I'),'Z', 'J'), '1', '9'),'2','8'),'3','7'),'4','6'),'5','5'),'6','4'),'7','3'),
'8','2'),'9','1'),' ','');

以上结果导致“8EVHUAB”和“8EVHHAB”都输出“2DFEENA”

更新 - - - - - - - - - - - - - - - - - - - - - - - - - ------------------

好的,我已经重做了代码,到目前为止有:

 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'

 SELECT @i = 1
 Select @Substring ='na'
 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 'END
 '

 END

但是,这不能正常工作,代码没有按其编写的那样执行,有什么建议吗?

4

3 回答 3

4

为什么你会看到这个: replace是一个函数;它所知道的只是它的论点。replace(replace('aba', 'a', 'b'), 'b', 'a')绝对等价于replace('bbb', 'b', 'a'),因为外部replace无法知道它的第一个参数是由对 的不同调用创建的replace。那有意义吗?

你可以把它想象成代数中的一个函数。如果我们定义 f(x) = x 2,则 f(f(2)) = f(2 2 ) = f(4) = 4 2 = 16。当参数为 f 时,无法告诉 f 表现不同(2) 从它的参数是 4 开始,因为 f(2)4。

同样,replace('aba', 'a', 'b') is 'bbb',所以没有办法告诉它的第一个参数是什么replace时候的行为不同于它的第一个参数是replace('aba', 'a', 'b')什么时候的行为'bbb'

(这在计算机科学中通常是正确的。计算机科学中的函数并不总是像代数中的函数——例如,它们经常实际做事,而不仅仅是返回一个值——但通常情况下它们接收参数作为值,或者作为对值的不透明引用,并且无法知道它们来自哪里或它们是如何构造的。)

如何解决这个问题:我认为没有任何非常干净的方法可以做到这一点。Gordon Linoff 建议您可以使用初始字符串中不存在且最终字符串中不存在的中间占位符(特别是小写字母),这样您就可以安全地replace使用它们而不必担心干扰;我认为这可能是最好的方法。

于 2012-07-24T19:21:17.740 回答
3

您的结果并不令人惊讶,因为每次替换都会将字符串返回到下一个级别。当它们是相同的字符时,无法区分原始字符值和替换值。

如果您只使用字母字符,则可以执行以下操作。

  1. 更改原始字符串的排序规则。
  2. 大写字符串
  3. 用小写字母替换大写字母
  4. 最后将整个字符串小写(应该是多余的)

不幸的是,我想不出一个可以以同样方式工作的数字的模拟。

这是一个网站的链接,该网站包含函数http://www.dbforums.com/microsoft-sql-server/1216565-oracle-translate-function-equivalent-sql-server.html的代码。Oracle 中的等效函数称为 translate。

于 2012-07-24T17:43:14.403 回答
2

Replace()函数只是执行操作并返回。它不会保持状态到下一个Replace()。它不会阻止以后的调用替换您之前替换的字符。要循环字符,您必须有一个额外的“占位符”值,然后注意不要替换已经从其他内容更改的字符。

首先,让我给你打个比方:

三个桶装满了相同数量的弹珠。这些桶被标记为“A”、“B”和“C”。您必须执行以下说明:

  • 将 A 中的所有弹珠倒入 C 中。
  • 将 B 中的所有弹珠倒入 A 中。
  • 将 C 中的所有弹珠倒入 B 中。

你希望得到什么结果?答案是:一个空桶 C,B 的弹珠数量是 A 的两倍。

如果您想保留原始数量的弹珠,则必须有四个容器,以免在移动弹珠时混合它们:

  • 将 C 中的所有弹珠倒入 X 中。
  • 将 A 中的所有弹珠倒入 C 中。
  • 将 B 中的所有弹珠倒入 A 中。
  • 将 X 中的所有弹珠倒入 B 中。(而不是从 C 中——已经有 A 的弹珠)

现在你得到了你期望的结果,并且可以丢弃空桶 X。

试试这个表达式,看看它是否给出了你想要的:

Replace(Replace(Replace(Replace('c', char(1)), 'a', 'c'), 'b', 'a'), char(1), 'b')
于 2012-07-24T19:19:09.937 回答