【问题标题】:execute query result statements执行查询结果语句
【发布时间】:2012-04-14 21:24:01
【问题描述】:

我有一组名为 results_% 的表,它们都具有相同的结构。

我想为这些表添加索引。

我可以将每个表的alter语句作为选择查询结果的一行,但我不知道如何执行这些语句:

select concat( 'alter table ', test_db.table_name, ' add index `did` (`did`);' ) as statement 
from information_schema.tables test_db 
where test_db.table_name like 'results_%';

我错过了什么?

输出(我想执行而不是只显示给我):

+---------------------------------------------------------+
| statement                                               |
+---------------------------------------------------------+
| alter table results_Em7777_spa add index `did` (`did`); |
| alter table results_KaEng_eng add index `did` (`did`);  |
| alter table results_Ka_spa add index `did` (`did`);     |
| alter table results_Mc_spa add index `did` (`did`);     |
| alter table results_Mo_eng add index `did` (`did`);     |
| alter table results_Pe_eng add index `did` (`did`);     |
| alter table results_SU_spa add index `did` (`did`);     |
| alter table results_Ta_spa add index `did` (`did`);     |
| alter table results_ba_eng add index `did` (`did`);     |
| alter table results_br_eng add index `did` (`did`);     |
| alter table results_ca_spa add index `did` (`did`);     |
| alter table results_ch_spa add index `did` (`did`);     |
| alter table results_da_spa add index `did` (`did`);     |
| alter table results_ga_eng add index `did` (`did`);     |
| alter table results_ge_spa add index `did` (`did`);     |
| alter table results_gk_eng add index `did` (`did`);     |
+---------------------------------------------------------+
16 rows in set (0.00 sec)

[编辑]

我试过了:

drop procedure if exists altlike; 
delimiter // 
create procedure altlike() 
begin 
   set group_concat_max_len = 65535; 
   select @altrlk:= concat( 'alter table ', test_db.table_name , ' add index `did` (`did`);' )
   from information_schema.tables test_db
   where test_db.table_name like "results_%"; 
   prepare statement from @altrlk; 
   execute statement; 
end // 
delimiter ; 
call altlike();

但仍然没有运气:它只会更改最后匹配的表 (results_gk_eng)。

【问题讨论】:

  • 你可以试试 PREPARE/EXECUTE: dev.mysql.com/doc/refman/5.1/en/…
  • 我也认为这是一个想法,但在阅读了文档后,我仍然无法弄清楚如何使用它们。
  • 有什么问题?编写一个遍历结果集并逐行执行的过程
  • 我什至没有运气尝试过:如果存在 altlike 则删除程序; delimiter // 创建过程 altlike(pattern varchar(128)) begin set group_concat_max_len = 65535; select @altrlk:= concat( 'alter table ', test_db.table_name , ' add index did (did);' ) from information_schema.tables where test_db.table_name like pattern;准备来自@altrlk 的声明;执行语句;结束 // 分隔符 ;调用 altlike("results_%");
  • @altrlk:= concat(... 语法非常错误。您需要从有关如何使用光标dev.mysql.com/doc/refman/5.1/en/cursors.html 的非常基础的知识开始

标签: mysql procedure concat


【解决方案1】:
drop procedure if exists `altlike`; 
DELIMITER // 
CREATE PROCEDURE `altlike` ()  
BEGIN
  DECLARE a,c VARCHAR(256);  
  DECLARE b INT;  
  DECLARE cur1 CURSOR FOR select concat(test_db.table_name)
  from information_schema.tables test_db 
  where test_db.table_name like 'results_%';
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1;
  DECLARE CONTINUE HANDLER FOR 1061 SET b = 0;  
  OPEN cur1;  
  SET b = 0;    
  WHILE b = 0 DO  
    FETCH cur1 INTO a;  
    IF b = 0 THEN
      SET @c = concat ('ALTER IGNORE TABLE `', a, '` ADD INDEX `did` (`did`)');
      PREPARE stmt1 FROM @c;
      EXECUTE stmt1; 
      DEALLOCATE PREPARE stmt1; 
    END IF;  
  END WHILE;  
  CLOSE cur1;       
END //  
call altlike();

【讨论】:

  • 这应该是正确答案,因为它回答了 OPs 问题
【解决方案2】:

你基本上是从数据库中打印出字符串行,它不会仅仅因为它看起来像一条 sql 语句而自动执行它;

您可以做的是使用编程语言逐行执行,然后返回结果。

或者把它扔到一个存储过程中,在那里它提供一个辅助执行块。

示例:FROM http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/ 了解更多信息。

DELIMITER //  

CREATE PROCEDURE `proc_CURSOR` (OUT param1 INT)  
BEGIN  
    DECLARE a, b, c INT;  
    DECLARE cur1 CURSOR FOR SELECT col1 FROM table1;  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1;  
    OPEN cur1;  

    SET b = 0;  
    SET c = 0;  

    WHILE b = 0 DO  
        FETCH cur1 INTO a;  
        IF b = 0 THEN  
            SET c = c + a;  
    END IF;  
    END WHILE;  

    CLOSE cur1;  
    SET param1 = c;  

END //  

【讨论】:

  • 我知道,我想知道是否有一种方法可以告诉 mysql 执行此输出,就像 mysql 过程一样,而不需要重复到外部脚本。
  • 另一个根本不是答案:-S
  • @zerkms 我相信这就是您写的评论“有什么问题?编写一个迭代结果集并逐行执行它的过程”,如果您实际阅读了代码,它确实做到了,除了它不完全是 alter 语句,但我不是来做他的工作,而是为他指出正确的方向。
  • @Churk:问题是“如何将字符串作为查询执行”而不是“如何编写基本 SP”。答案并没有说明真正的问题。 OP 不知道如何执行动态查询,但知道如何编写 SP。所以,我不知道你复制粘贴的 SP 有什么帮助
  • 可能你是部分正确的,并且 OP 不知道如何使用光标,抱歉 ;-)