2012-01-26 3 views
1

RESOLU:Impossible de créer une procédure MySQL avec une boucle

Cela fonctionne:

DROP PROCEDURE IF EXISTS drop_all_tables_from_specified_database; 

DELIMITER $$ 
CREATE PROCEDURE drop_all_tables_from_specified_database(IN dbname CHAR(50)) 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE tblname CHAR(50); 
    DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = dbname COLLATE utf8_general_ci; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    SET foreign_key_checks = 0; 

    OPEN cur1; 

    read_loop: LOOP 
     FETCH cur1 INTO tblname; 
     IF done THEN 
      LEAVE read_loop; 
     END IF; 

     SET @database_name = dbname; 
     SET @table_name = tblname; 
     SET @sql_text = CONCAT('DROP TABLE ', @database_name, '.' , @table_name, ';');  

     PREPARE stmt FROM @sql_text; 
     EXECUTE stmt; 
     DEALLOCATE PREPARE stmt; 

    END LOOP; 

    CLOSE cur1; 

    SET foreign_key_checks = 1; 
END$$ 
DELIMITER ; 

CALL drop_all_tables_from_specified_database('test'); 

DROP PROCEDURE drop_all_tables_from_specified_database; 

Je suis en train de créer une procédure qui supprime toutes les tables dans une base de données. J'ai sauvé ce code dans un fichier déchirure down.sql:

CREATE PROCEDURE drop_all_tables_from_specified_database() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE table_to_drop VARCHAR(255); 
    DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema='test'; 

    OPEN cur1; 

    read_loop: LOOP 
     FETCH cur1 INTO table_to_drop; 
     IF done: 
      LEAVE read_loop; 
     END IF; 
     DROP TABLE `test`.table_to_drop; 
    END LOOP; 

    CLOSE cur1; 
END; 

Quand je puis faire à l'intérieur outil de ligne de commande MySQL:

mysql> source tear-down.sql 

J'obtiens une erreur énorme:

enter image description here

Je ne comprends pas l'erreur que je reçois et je n'arrive pas à comprendre ce qui ne va pas. Quelqu'un peut-il repérer une erreur dans cette procédure?

EDIT:

Mon code actuel:

DROP PROCEDURE IF EXISTS drop_all_tables_from_specified_database; 

DELIMITER $$ 
CREATE PROCEDURE drop_all_tables_from_specified_database(IN dbname CHAR(50)) 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE tblname CHAR(50); 
    DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = dbname; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    OPEN cur1; 

    read_loop: LOOP 
     FETCH cur1 INTO tblname; 
     IF done THEN 
      LEAVE read_loop; 
     END IF; 
     DROP TABLE dbname.tblname; 
    END LOOP; 

    CLOSE cur1; 
END$$ 
DELIMITER ; 

CALL drop_all_tables_from_specified_database('test'); 

DROP PROCEDURE drop_all_tables_from_specified_database; 

Maintenant il fonctionne ok, mais il ne supprime pas les tables. Je reçois cette réponse:

enter image description here

Répondre

1

Il semble que vous devez définir une autre DELIMITER:

DELIMITER $$ 
CREATE PROCEDURE drop_all_tables_from_specified_database() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE table_to_drop VARCHAR(255); 
    DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema='test'; 

    OPEN cur1; 

    read_loop: LOOP 
     FETCH cur1 INTO table_to_drop; 
     /* This might need to be 'IF done <> FALSE THEN' */ 
     IF done THEN 
      LEAVE read_loop; 
     END IF; 
     DROP TABLE `test`.table_to_drop; 
    END LOOP; 

    CLOSE cur1; 
END$$ 
DELIMITER ; 
+0

Cela a aidé un peu, mais maintenant je me différencie, plus petite erreur. Je ne vois aucune erreur de syntaxe là-bas? Vérifiez ma question mise à jour, s'il vous plaît. –

+0

Apparemment, j'utilise des mots réservés? Je n'en vois pas. –

+0

@RichardKnop Vous n'avez pas remarqué que votre syntaxe 'IF' était foirée. Utilisez 'IF condition THEN', plutôt que' IF condition: '. Voir au dessus. –

0

Il devrait être IF done THEN pas IF done:. La variable "done" n'est pas mise à jour pour que vous puissiez y avoir une boucle infinie. Jetez un oeil à fetch cursor into.

+0

Je l'ai déjà résolu. Vérifiez ma question mise à jour. Encore obtenir la même erreur. –

+0

Cela a bien fonctionné pour moi sauf que j'ai fait un changement, probablement la version de mysql. J'ai changé le code suivant: 'CREATE PROCEDURE drop_all_tables_from_specified_database' à ' CREATE PROCEDURE test.drop_all_tables_from_specified_database' – vimdude

Questions connexes