【问题标题】:Run MySQL queries on different databases在不同的数据库上运行 MySQL 查询
【发布时间】:2014-08-17 13:10:21
【问题描述】:

我们有一个系统,每个部门都有一个数据库,目前我们有 20 多个部门。

所以当我们必须更新/删除/更改/新表时,我们必须扔掉所有这些数据库并运行查询。

有时人们不遵守程序(总是?),我们最终会得到没有更新的结构。

我正在寻找一种无需使用 bash 或外部脚本即可在所有数据库上进行相同查询的方法。

所以这是我找到的一些东西:

CALL FOR EACH("SELECT databases WHERE `DATABASE` LIKE 'division_%'" , ${1});

我可以在 ${1} 中输入查询

或者这个(不那么动态):

call $('{a, b}'   , 'ALTER TABLE division_${1}.caching ADD COLUMN notes VARCHAR(4096) CHARSET utf8'');

但这给了我“未选择数据库

关于如何处理这种情况的任何想法?

【问题讨论】:

  • 这里不是一个有用的响应,但如果它们是同一个系统的一部分,这应该是同一个数据库。稍微有用的回复,如果您查看准备好的语句,它们可能会对您有所帮助(dev.mysql.com/doc/refman/5.6/en/…
  • @Simonatmso.net 我同意......我们从另一家公司得到了这个漂亮的项目......无论如何它有利有弊(很多条目 650k+ / 表).. 很快就会发布解决方案我找到了。

标签: mysql multiple-databases dynamic-queries


【解决方案1】:

这是我找到的解决方案,它有效:

USE division_global;

DELIMITER $$

CREATE PROCEDURE `MultipleSchemaQuery`()
BEGIN
    declare scName varchar(250);
    declare q varchar(2000);

    DROP TABLE IF EXISTS ResultSet;
    create temporary table ResultSet (
     option_value varchar(200)
    );

    DROP TABLE IF EXISTS MySchemaNames;
    create temporary table MySchemaNames (
        schemaName varchar(250)
    );

    insert into MySchemaNames
    SELECT distinct
        TABLE_SCHEMA as SchemaName
    FROM 
        `information_schema`.`TABLES`  
    where 
         TABLE_SCHEMA LIKE 'division_%';

label1:
    LOOP
        set scName = (select schemaName from MySchemaNames limit 1);
        // The Query
        set @q = concat('TRUNCATE TABLE ', scName, '.caching');
        PREPARE stmt1 FROM @q;
        EXECUTE stmt1;
        DEALLOCATE PREPARE stmt1;

        delete from MySchemaNames where schemaName = scName;
        IF ((select count(*) from MySchemaNames) > 0) THEN
            ITERATE label1;
        END IF;
        LEAVE label1;

    END LOOP label1;

    SELECT * FROM ResultSet;

    DROP TABLE IF EXISTS MySchemaNames;
    DROP TABLE IF EXISTS ResultSet;
END
$$

受此启发:

Querying multiple databases at once

【讨论】:

    【解决方案2】:

    您将需要使用存储过程和一些准备好的语句,正如 Simon 在 cmets 中指出的那样:

    cat procedure.sql
    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS alter_all $$
    
    CREATE PROCEDURE alter_all()
    BEGIN
      DECLARE done INT DEFAULT 0;
      DECLARE _schema VARCHAR(30);
      DECLARE cur CURSOR FOR select SCHEMA_NAME from information_schema.SCHEMATA where SCHEMA_NAME like 'division_%';
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := 1;
    
      OPEN cur;
    
      alterLoop: LOOP
        FETCH cur into _schema;
        if done = 1 THEN
          LEAVE alterLoop;
        END IF;
        SET @mystmt = concat('ALTER TABLE ', _schema, '.caching ADD COLUMN notes VARCHAR(4096)');
        PREPARE stmt3 FROM @mystmt;
        EXECUTE stmt3;
        DEALLOCATE PREPARE stmt3;
      END LOOP alterLoop;
    
      CLOSE cur;
    
    END $$
    
    DELIMITER ;
    

    有了它,让我们试试吧(使用服务器版本:5.5.35-0ubuntu0.12.04.2 (Ubuntu)):

    > create schema division_1 default character set 'UTF8';
    > create table division_1.caching (id int not null auto_increment primary key, value varchar(10));
    > create schema division_2 default character set 'UTF8';
    > create table division_2.caching (id int not null auto_increment primary key, value varchar(10));
    > use division_1;
    > source procedure.sql
    > CALL alter_all();
    Query OK, 0 rows affected, 1 warning (0.05 sec)
    > desc caching;
    +-------+---------------+------+-----+---------+----------------+
    | Field | Type          | Null | Key | Default | Extra          |
    +-------+---------------+------+-----+---------+----------------+
    | id    | int(11)       | NO   | PRI | NULL    | auto_increment |
    | value | varchar(10)   | YES  |     | NULL    |                |
    | notes | varchar(4096) | YES  |     | NULL    |                |
    +-------+---------------+------+-----+---------+----------------+
    > desc division_2.caching
    +-------+---------------+------+-----+---------+----------------+
    | Field | Type          | Null | Key | Default | Extra          |
    +-------+---------------+------+-----+---------+----------------+
    | id    | int(11)       | NO   | PRI | NULL    | auto_increment |
    | value | varchar(10)   | YES  |     | NULL    |                |
    | notes | varchar(4096) | YES  |     | NULL    |                |
    +-------+---------------+------+-----+---------+----------------+
    

    【讨论】:

    • 它看起来像我添加的,但我想要的更多的是多个查询(有时我们有超过 100 个查询要运行)
    • 然后您可以将查询作为 proc 参数进行构建,或者将查询存储在表中并从那里加载,而不是仅针对一种情况执行 concat。
    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 2016-02-24
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多