按列类型更新表

时间:2014-07-09 18:55:08

标签: mysql

我有一个包含敏感数字的大型MYSQL数据表。我们需要一家外部公司为我们制作一款能消耗数据的应用程序。我们不想给他们真实的数字。相反,我想伪造数据。这是我正在尝试的

样本表

Name<varChar> | col1 <int>| col2 <decimal>| coln <int>
Joe           |  1        |  2            |  3

我想编写一个脚本,通过获取当前实际值并将其乘以大于ZERO的随机数来更新所有整数或小数列(基本上是数字的任何列)。

这是我编写的代码块,它位于正确的轨道上。

UPDATE TABLE SET VALUE=VALUE*ROUND(RAND());

但缺少以下内容:

1)仅更新一列

2)不验证该列是否为数字数据

有人可以帮助使用这个sql脚本。

3 个答案:

答案 0 :(得分:1)

这是一个仅限mysql的解决方案。您可以按类型查询information_schema表中的列,然后使用变量构建您的SQL查询。

mysql> CREATE TABLE example (
    ->          id INT,
    ->          data VARCHAR(100),
    ->          id2 INT,
    ->          id3 decimal,
    ->          id4 double,
    ->          id5 float,
    ->          id6 numeric   
    ->        );
Query OK, 0 rows affected (0.10 sec)

mysql> insert into example values (1,'hello',2,3,4,5,6);
Query OK, 1 row affected (0.05 sec)

mysql> SET @sql = NULL;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT GROUP_CONCAT(CONCAT(column_name,'=ROUND(',column_name,'*RAND())'))
    -> INTO @sql
    -> FROM information_schema.columns 
    -> WHERE table_schema = 'test' -- your db name
    -> AND table_name = 'example' 
    -> AND (column_type LIKE  '%int%'
    -> OR column_type LIKE '%decimal%'
    -> OR column_type LIKE '%numeric%'
    -> OR column_type LIKE '%float%'
    -> OR column_type LIKE '%double%');
Query OK, 1 row affected (0.00 sec)

mysql> SET @sql1 = CONCAT("UPDATE example SET ",@sql);
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE stmt FROM @sql1;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE stmt;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from example;
+------+-------+------+------+------+------+------+
| id   | data  | id2  | id3  | id4  | id5  | id6  |
+------+-------+------+------+------+------+------+
|    0 | hello |    0 |    3 |    4 |    1 |    3 |
+------+-------+------+------+------+------+------+
1 row in set (0.00 sec)

mysql> select @sql1;
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| @sql1                                                                                                                                                |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| UPDATE example SET id=ROUND(id*RAND()),id2=ROUND(id2*RAND()),id3=ROUND(id3*RAND()),id4=ROUND(id4*RAND()),id5=ROUND(id5*RAND()),id6=ROUND(id6*RAND()) |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

答案 1 :(得分:0)

我知道你想用Java做这件事。您可以使用系统表或ResultSetMetaData完全自动执行此操作。

伪代码:

  • 获取与表名称排序的数字数据类型匹配的用户表和列的完整列表。 (MySQL应该有一个SQL查询来从系统表或视图中获取此信息。)
  • 对于每个表,构建并执行update语句,使用随机乘法更新所有列。

替代伪代码:

  • 获取用户表的完整列表。
  • 对于每个表,获取一行数据(无论哪一行都不重要,因为您不会迭代ResultSet)。
  • 使用ResultSetMetaData对象获取列名和数据类型。
  • 构建并执行update语句,使用随机乘法更新与数值数据类型匹配的所有列。

与往常一样,针对可以使用数据库构建脚本重置的小型测试数据库运行程序。它应该包含一些包含各种数据类型的列和数据的表。

答案 2 :(得分:0)

如果您只想在mysql中使用java来执行此查询。

UPDATE table t,
(
    SELECT id,
        col1*FLOOR(RAND() * 9) +1 as c1,
        col2*FLOOR(RAND() * 9) +1 as c2,
        col3*FLOOR(RAND() * 9) +1 as c3
    FROM table
) as temp
SET temp.c1 = t.col1, temp.c2 = t.col2, temp.c3 = t.col3 WHERE t.id = temp.id;

两件事: FIRST 这假设您为每一行都有一个唯一的ID,因为所有规范化的表都应具有此ID。 SECOND 您的随机数范围可以更改为您想要的任何内容,只需将FLOOR(RAND() * 9)更改为其他内容... FLOOR(min * max)..所以使9 a不同的数字来改变范围。我最后添加1的原因是你不希望数字改为0然后在FLOOR之后添加一个使其至少为1


修改 处理检查是否数字,然后只是如此简单的IF比较:

UPDATE table t,
(
    SELECT id,
        IF(col1 >=0, col1*FLOOR(RAND() * 9) +1, col1) as c1,
        IF(col2 >=0, col2*FLOOR(RAND() * 9) +1, col2) as c2,
        IF(col3 >=0, col3*FLOOR(RAND() * 9) +1, col3) as c3
    FROM table
) as temp
SET temp.c1 = t.col1, temp.c2 = t.col2, temp.c3 = t.col3 WHERE t.id = temp.id;