【发布时间】:2019-03-10 09:47:00
【问题描述】:
我正在寻找一种有效的方法来覆盖需要混合的给定表和字段列表。
我想这应该变成一个函数或存储过程。
输入应该是某种表名列表,每个表应该有另一个列表,其中包含唯一索引列、键列以及所有其他需要混合的列。
算法和给定代码解释如下:
首先,混合是指保留每列中的所有值,但以不同的顺序在行之间重新分配它们。
SQL 语法:
declare @tablename varchar, @keyColumn varchar, @ColumnForBase ,@ColumnToMix
update [@tablename]
set [@tablename].[@ColumnToMix]=c.[@ColumnToMix],[@tablename].[@ColumnForBase]=c.[@ColumnForBase]
from [@tablename] left join
(
SELECT a.[@ColumnToMix] as [@ColumnToMix] ,b.[@ColumnForBase] as [@ColumnForBase],b.[@keyColumn] as [@keyColumn]
FROM
(SELECT row_number() OVER (ORDER BY [@ColumnToMix]) num, [@ColumnToMix]
FROM [@tablename]) as a
left join
(SELECT row_number() OVER (ORDER BY [@ColumnForBase]) num, [@keyColumn],[@ColumnForBase]
FROM [@tablename] ) as b
ON a.num=b.num
)as c ON c.[@keyColumn]=[@tablename].[@keyColumn]
说明和例子:
假设我有一个包含 4 列的表:索引、ID、名称、地址 该算法对 ID 和名称重新排序,在每一行添加一个数字。 由于行数相同,我可以通过行号连接两个重新排序的列,然后更新原始表 - 将一列 (ColumnToMix) 更改为重新分配的值。 假设原始表名为“People”,如下所示:
Index Id Name Address
1 52 Jill New-York
2 57 John Chicago
5 63 Bill Alabama
变量是 @tablename = 人,@keyColumn = 索引,@ColumnForBase = Id,@ColumnToMix = 名称
上面的代码运行结果是
Index Id Name Address
1 52 Bill New-York
2 57 Jill Chicago
5 63 John Alabama
现在名字混在一起了。
为了混合多于一列,代码需要能够遍历所有必要的字段。
有什么想法吗?
【问题讨论】:
-
这似乎是一个危险的想法......行是一个数据单元,像你描述的那样混合数据库中的特定列(或列)意味着将数据弄乱到一个点将不再有意义并且可能不会回头(恢复较旧的备份除外)。你为什么要做这样的事情?
-
这个想法是有意混合数据以获得随机不同的数据集。它对 QA 有好处,也可用于将取自真实环境的数据打乱到测试环境中。
-
...也可以用于(错误地或恶意地)将生产数据库更改为无法使用的程度,或者甚至可以破解它(在用户表中混合用户名或密码, 例如)。顺便说一句,如果您指定您正在使用的 rdbms(品牌和版本),您将更有可能获得答案
-
谢谢,添加了 rdbms 规范。关于用法 - 任何 DELETE 或 DROP TABLE 都可能同样或更危险,显然这应该谨慎使用......
标签: sql sql-server algorithm loops sql-server-2008-r2