【问题标题】:Updating all rows of a particular column in every table of a specific database (Mysql)更新特定数据库(Mysql)的每个表中特定列的所有行
【发布时间】:2019-06-22 03:16:36
【问题描述】:

我正在尝试更新数据库中每个表中列的所有行。我当前的 SQL 如下所示:

SELECT CONCAT('UPDATE `', a.table_name, '` SET columnName = NULL;')
FROM information_schema.tables a
WHERE a.table_schema = 'databaseName'   

当我运行这个命令时,我会运行一系列命令,例如:

UPDATE `Friday` SET columnName = NULL;

Frid​​ay 是我指定的数据库中的表之一。问题是当我运行它时,表本身没有任何更改。如果我要采用我的串联输出的命令之一并运行它,那么该表就会受到影响。我对使用 MySQL 有点陌生,那么为什么串联的一系列命令与单个命令运行会改变效果?对于我想要实现的目标,我的初始命令的格式是否不正确?感谢您的帮助!

编辑:根据发布的 cmets 和文档,这里是我所在位置的更新。

SET @s:='';
SELECT @s:=concat(@s, 'UPDATE TABLE ', a.TABLE_SCHEMA,'.`',  a.TABLE_NAME, '` SET columnName = NULL;') FROM INFORMATION_SCHEMA.TABLES a where table_schema = 'databaseName';    
PREPARE stmt FROM @s;
EXECUTE stmt;

DEALLOCATE PREPARE stmt;

仔细阅读文档,发现准备好的语句不适用于多个语句。调查程序。

编辑:

这更接近我想要完成的目标。尽管如此,还是有一些我需要解决的错误。

    DELIMITER $$

DROP PROCEDURE IF EXISTS myproc $$

CREATE PROCEDURE myproc() 
NOT DETERMINISTIC
MODIFIES SQL DATA
BEGIN

DECLARE done tinyint(1) DEFAULT FALSE;
DECLARE sql2 VARCHAR(2000);

DECLARE csr CURSOR FOR 
SELECT CONCAT('UPDATE `',c.table_schema,'`.`',c.table_name,'` SET `columnName` = NULL') AS sql2
    FROM information_schema.columns c
   WHERE c.column_name = 'columnName'
     AND c.table_schema IN ('databaseName');
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN csr;
  do_foo: LOOP
     FETCH csr INTO sql2;
     IF done THEN
        LEAVE do_foo;
     END IF;
     PREPARE stmt FROM sql2;
     EXECUTE stmt;
     DEALLOCATE PREPARE stmt;
  END LOOP do_foo;
  CLOSE csr;

  END$$

DELIMITER ;

【问题讨论】:

  • 目前还不清楚观察到什么行为。说“没有对表进行任何更改”和“表会受到影响”对于确定正在使用的客户端实际上是没有用的;使用什么机制从 SELECT 中获取结果集,并将这些字符串作为 SQL 语句执行。运行该 SELECT 语句只会返回一个结果集。 CONCAT 表达式的结果是什么无关紧要。它恰好看起来像 SQL 文本并没有任何区别。 (SELECT 只是返回数据类型为 VARCHAR 的列。)
  • 重申一下,当您将SELECT语句提交给MySQL服务器执行时,该语句成功完成,并且MySQL服务器返回一个结果集。通常,客户端从结果集中获取行并将它们显示为文本 ala mysql 命令行客户端。 (就客户端而言,返回的不是“一系列命令”。返回的是一个结果集,如表、一组或由数据类型为 VARCHAR 的单个列组成的行。)
  • @spencer7593 抱歉刚开始使用 MySQL。是的,然后在使用我发布的 sql sn-p 时返回一个结果集。我假设它会像普通的 sql 语句一样运行它们。我应该如何在结果集中运行每个结果?
  • 我的最终目标是在预定事件中运行所有这些语句。有没有办法循环遍历结果列表并执行 mysql 事件中的每个语句?
  • 我怀疑您需要创建更新语句并将它们提交到 mysql 参见dev.mysql.com/doc/refman/8.0/en/…。 AND 循环遍历所有表将代码放入存储过程中。顺便说一句,您真的在要更新的所有表中都有一个名为 columnname 的列吗?

标签: mysql sql-update concat


【解决方案1】:

这是我想出的解决方案。感谢那些评论并指出我正确方向的人。如果将来有人需要更新数据库中的每一列,这就是我所做的:

DELIMITER $$

DROP PROCEDURE IF EXISTS myproc $$

CREATE PROCEDURE myproc() 
NOT DETERMINISTIC
MODIFIES SQL DATA
BEGIN

DECLARE done tinyint(1) DEFAULT FALSE;
DECLARE sql2 VARCHAR(2000);

DECLARE csr CURSOR FOR 
SELECT CONCAT('UPDATE ',c.table_schema,'.`',c.table_name,'` SET columnName = NULL') AS sql2
    FROM information_schema.columns c
   WHERE c.column_name = 'columnName'
     AND c.table_schema IN ('databaseName');
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN csr;
  do_foo: LOOP
     FETCH csr INTO sql2;
     IF done THEN
        LEAVE do_foo;
     END IF;

     SET @newTest = sql2;
     PREPARE stmt FROM @newTest;
     EXECUTE stmt;
     DEALLOCATE PREPARE stmt;
  END LOOP do_foo;
  CLOSE csr;

  END$$

DELIMITER ; 

【讨论】:

    猜你喜欢
    • 2014-08-13
    • 1970-01-01
    • 2021-12-24
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多