2014-06-26 27 views
3

我们有一个系统,每个部门都有一个数据库,目前我们有20多个部门。在不同的数据库上运行MySQL查询

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

某些时候人们不遵循程序(总是?),并且我们最终没有更新结构。

我正在寻找一种方法来在所有数据库上吃同样的查询,而不必使用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''); 

但这给了我“没有数据库选中

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

+0

不是一个有用的响应这里,但实际上这应该是相同的数据库,如果它们是同一系统的一部分。 稍微有用的回应,如果你看准备好的语句,他们可能会帮助你(http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html) –

+0

@ Simonatmso.net我同意......我们从另一家公司获得了这个漂亮的项目......无论如何它有优点和缺点(很多条目650k + /表格)..我很快发布了一个解决方案。 – Tarek

回答

0

这是一个解决方案,我发现它的工作原理:

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

0

您需要使用存储过程和一些准备的语句西蒙指出,在评论中:

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 |    | 
+-------+---------------+------+-----+---------+----------------+ 
+0

它看起来像我添加的一个,但我想要的更多的是多个查询(有时我们有超过100个查询运行) – Tarek

+0

然后,您可以将查询作为proc参数构建或将查询存储在表中并从而不是只对一个案例进行concat。 –