Mysql
 sql >> Database >  >> RDS >> Mysql

Cursore dinamico nella procedura memorizzata

Dal Manuale MySQL

Tuttavia ci sono 2 modi.

Il primo è per i casi in cui solo un utente alla volta eseguirà la procedura. È possibile utilizzare un'istruzione prepare per creare una vista con l'SQL dinamico e il cursore può selezionare da questa vista con nome statico. Non c'è quasi nessun impatto sulle prestazioni. Sfortunatamente, queste visualizzazioni sono visibili anche ad altri utenti (non esiste una visualizzazione temporanea), quindi non funzionerà per più utenti.

Analogamente, è possibile creare una tabella temporanea nell'istruzione prepare e il cursore può selezionare dalla tabella temporanea. Solo la sessione corrente può vedere una tabella temporanea, quindi il problema con più utenti è stato risolto. Ma questa soluzione può avere un impatto significativo sulle prestazioni poiché è necessario creare una tabella temporanea ogni volta che viene eseguito proc.

In conclusione:abbiamo ancora bisogno dei cursori per poter essere creati dinamicamente!

Ecco un esempio di utilizzo di una vista per passare il nome della tabella e della colonna in un cursore da 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 ;