Mysql
 sql >> Base de données >  >> RDS >> Mysql

Curseur dynamique dans une procédure stockée

À partir du Manuel MySQL

Cependant, il y a 2 façons.

Le premier concerne les cas où absolument un seul utilisateur à la fois exécutera la procédure. Une instruction de préparation peut être utilisée pour créer une vue avec le SQL dynamique et le curseur peut sélectionner à partir de cette vue nommée de manière statique. Il n'y a presque aucun impact sur les performances. Malheureusement, ces vues sont également visibles pour les autres utilisateurs (il n'y a pas de vue temporaire), donc cela ne fonctionnera pas pour plusieurs utilisateurs.

De manière analogue, une table temporaire peut être créée dans l'instruction de préparation et le curseur peut effectuer une sélection dans la table temporaire. Seule la session en cours peut voir une table temporaire, le problème d'utilisateurs multiples est donc résolu. Mais cette solution peut avoir un impact significatif sur les performances car une table temporaire doit être créée à chaque exécution du proc.

Conclusion :nous avons encore besoin de curseurs pour pouvoir être créés dynamiquement !

Voici un exemple d'utilisation d'une vue pour transmettre le nom de la table et le nom de la colonne dans un curseur depuis le forum mysql

DELIMITER // 
DROP PROCEDURE IF EXISTS test_prepare// 

CREATE PROCEDURE test_prepare(IN tablename varchar(255), columnname varchar(50)) 
BEGIN 
DECLARE cursor_end CONDITION FOR SQLSTATE '02000'; 
DECLARE v_column_val VARCHAR(50); 
DECLARE done INT DEFAULT 0; 
DECLARE cur_table CURSOR FOR SELECT * FROM test_prepare_vw; 
DECLARE CONTINUE HANDLER FOR cursor_end SET done = 1; 

SET @query = CONCAT('CREATE VIEW test_prepare_vw as select ', columnname, ' from ', tablename); 
select @query; 
PREPARE stmt from @query; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

OPEN cur_table; 
FETCH cur_table INTO v_column_val; 
WHILE done = 0 DO 
SELECT v_column_val; 
FETCH cur_table INTO v_column_val; 
END WHILE; 
CLOSE cur_table; 

DROP VIEW test_prepare_vw; 

END; 
// 

DELIMITER ;