Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Cursor dinâmico em procedimento armazenado


Do Manual MySQL

No entanto, existem 2 maneiras.

A primeira é para casos em que absolutamente apenas um usuário de cada vez estará executando o procedimento. Uma instrução prepare pode ser usada para criar uma visualização com o SQL dinâmico e o cursor pode selecionar a partir dessa visualização nomeada estaticamente. Quase não há impacto no desempenho. Infelizmente, essas visualizações também são visíveis para outros usuários (não existe uma visualização temporária), portanto, isso não funcionará para vários usuários.

Analogamente, uma tabela temporária pode ser criada na instrução prepare e o cursor pode selecionar na tabela temporária. Somente a sessão atual pode ver uma tabela temporária, portanto, o problema de vários usuários é resolvido. Mas essa solução pode ter um impacto significativo no desempenho, pois uma tabela temporária deve ser criada toda vez que o proc é executado.

Conclusão:ainda precisamos de cursores para poder ser criado dinamicamente!

Aqui está um exemplo de uso de uma visualização para passar o nome da tabela e o nome da coluna para um cursor do fóruns 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 ;