2016-01-23 49 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