2016-01-23 72 views
-1

我想创建一个mysql存储过程可以循环并获取动态sql而不使用游标。循环MySQL动态SQL

让我们说,我有

SET @SQLSTATEMENT = CONCAT('SELECT FLD1,FLD2 FROM TABLE1 WHERE FLD1 = \'',PARAM1,'\';'); 
PREPARE stmt FROM @SQLSTATEMENT; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

不使用光标我想这种说法,遍历的结果,并创建里面另一个SELECT语句。

的理念是一样的东西

Execute SQLStatement 
Get Result 

Loop 
    fetch columns 
    execute another sql statement 
    get result 
    loop 
     fetch columns 
     fire insert statement 
    end loop 
End Loop 

要做到这一点,我需要建立两个或更多的程序与光标。有没有办法在一个程序中做到这一点?

请帮忙。谢谢

+0

你为什么不使用游标? –

+0

嗨@EdHeal,我只是在MySQL存储过程newby,如果我是正确的游标必须在任何设置或行之前声明。在这种情况下,我们将需要两个游标 – bob

+2

是关于学习sprocs还是关于完成特定任务的练习? – Strawberry

回答

1

我只是没有这样

CREATE DEFINER=`root`@`%` PROCEDURE `ProcSample`(
In Parameter1 VARCHAR(4), 
In Parameter2 VARCHAR(2), 
In Parameter3 VARCHAR(2), 
In Paremeter4 VARCHAR(2) 
) 
BEGIN 

DECLARE i INT(11); 
DECLARE j INT(11); 
DECLARE SCHEMACOUNT INT(11); 
DECLARE TABLENAME VARCHAR(100); 
DECLARE RECORDCOUNT INT(11); 


Delete from `sampledb`.`sampletable`; 

SET @SCHEMACOUNT = 0; 
SET @SQLSTATEMENT = CONCAT(' 
    SELECT DISTINCT COUNT(TABLE_NAME) INTO @SCHEMACOUNT FROM information_schema.`TABLES` 
    WHERE TABLE_SCHEMA LIKE \'%String%\' AND TABLE_SCHEMA NOT LIKE \'%String%\' 
    AND TABLE_NAME LIKE \'%String%',Parameter1,Parameter2,'%\';' 
); 
PREPARE stmt FROM @SQLSTATEMENT; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 


SET @TABLENAME = ''; 
SET @i = 0; 
WHILE @i < @SCHEMACOUNT DO 

    SET @SQLSTATEMENT = CONCAT(' 
     SELECT DISTINCT CONCAT(TABLE_SCHEMA,\'.\',TABLE_NAME) INTO @TABLENAME FROM information_schema.`TABLES` 
     WHERE TABLE_SCHEMA LIKE \'%String%\' AND TABLE_SCHEMA NOT LIKE \'%String%\' 
     AND TABLE_NAME LIKE \'%String%',Parameter1,Parameter2,'%\' 
     ORDER BY TABLE_SCHEMA,TABLE_NAME 
     LIMIT 1 OFFSET ',@i 
    ); 
    PREPARE stmt FROM @SQLSTATEMENT; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 

    SET @RECORDCOUNT = 0; 
    SET @SQLSTATEMENT = CONCAT(' 
     SELECT DISTINCT COUNT(`IndexKey`) INTO @RECORDCOUNT FROM ',@TABLENAME,' 
     WHERE `Field1` = \'Value1\' and `Field2` = \'Value2\` ' 
    ); 


    PREPARE stmt FROM @SQLSTATEMENT; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 

    SET @j = 0 ; 
    WHILE @j < @RECORDCOUNT DO 
     SET @SQLSTATEMENT = CONCAT(' 
      INSERT INTO `sampledb`.`sampletable` 
      (`Field1`,`Field2`,`Field3`) 
      SELECT `Field1`,`Field2`,`Field3` FROM ',@TABLENAME,' 
      WHERE `Field1` = \'Value1\' and `Field2` = \'Value2\` 
      LIMIT 1 OFFSET ',@j,';' 
     ); 

     PREPARE stmt FROM @SQLSTATEMENT; 
     EXECUTE stmt; 
     DEALLOCATE PREPARE stmt; 


     SET @j = @j + 1; 
    END WHILE; 


    SET @i = @i + 1; 
END WHILE; 



END 
+1

这似乎有点讨厌,但这正是我所期待的。另外,我建议你将来自'information.schema'的行计算为使用'FOUND_ROWS()'的语句。它将是:'SET @SCHEMACOUNT = FOUND_ROWS();'。 – Deckard