MYSQL - Procedure para criação de views
Tenho o seguinte cenário: Uma instância do Mysql com pelo menos 23 bases de dados. Todas elas começam com o nome "Empresa_Homologacao_Cliente". Atualmente estou criando uma procedure em ambiente de homologação que cria views de modo automático em cada uma das bases de dados.
Na procedure segmentei para buscar de modo separado o corpo de select da view com as instruções de Use , Drop e Create (Use base de dados, drop view e create view respectivamente). Segue o código para entender:
Ocorre que quando executo a procedure a construção de como vai ser o texto final que precisaria executar manualmente é "printado" pela variável @queryStatement mas no Mysql apresenta a mensagem de erro: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP VIEW IF EXISTS".
Se eu copio o retorno que a procedure gera e executo manualmente funciona, mas via procedure automático não. Por que?
Na procedure segmentei para buscar de modo separado o corpo de select da view com as instruções de Use , Drop e Create (Use base de dados, drop view e create view respectivamente). Segue o código para entender:
DROP PROCEDURE IF EXISTS CreateViewsVendas; DELIMITER // CREATE PROCEDURE `CreateViewsVendas`(IN DB VARCHAR(255)) DETERMINISTIC COMMENT 'TESTE PROCEDURE VIEWS' BEGIN DECLARE qStr TEXT DEFAULT ''; DECLARE queryStatement TEXT DEFAULT ''; DECLARE cursor_VAL VARCHAR(255) DEFAULT ''; DECLARE done INTEGER DEFAULT 0; DECLARE cursor_i CURSOR FOR SELECT DISTINCT CONCAT('empresa_homologacao_',(table_schema)) FROM information_schema.tables WHERE table_schema LIKE CONCAT('empresa_homologacao_',DB); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cursor_i; read_loop: LOOP FETCH cursor_i INTO cursor_VAL; IF done = 1 THEN LEAVE read_loop; END IF; SET qStr = ('SELECT CORPO DA VIEW'); END LOOP; CLOSE cursor_i; SET @qStr = CONCAT('USE empresa_homologacao_',DB,'; ','DROP VIEW IF EXISTS view_que_quero_criar; ', 'CREATE VIEW view_que_quero_criar AS ', qStr); SET @queryStatement=(SELECT @qStr); SELECT @queryStatement; PREPARE stmt FROM @queryStatement; EXECUTE stmt; DEALLOCATE PREPARE stmt; END// DELIMITER ;
Ocorre que quando executo a procedure a construção de como vai ser o texto final que precisaria executar manualmente é "printado" pela variável @queryStatement mas no Mysql apresenta a mensagem de erro: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP VIEW IF EXISTS".
Se eu copio o retorno que a procedure gera e executo manualmente funciona, mas via procedure automático não. Por que?
Chromusmaster
Curtidas 0
Melhor post
Alex William
17/11/2020
Olá amigo, tudo bem?
Consegui rodar sua procedure somente assim:
E quando dei um "CALL" nela, com o codigo:
Ela retornou:
Era isso que ela deveria retornar?
Eu tive que remover um monte de espaços que tinham no seu codigo, mas creio que seja pq você usou a citação ao invés da tag code do fórum.
Única coisa que eu troquei é o delimitador, pois // é pra função e não consegui executar para procedure, então tive que trocar para $$.
E dessa forma funcionou...
Espero ter ajudado. :D
Consegui rodar sua procedure somente assim:
DROP PROCEDURE IF EXISTS CreateViewsVendas; DELIMITER $$ CREATE PROCEDURE CreateViewsVendas(IN DB VARCHAR(255)) DETERMINISTIC COMMENT 'TESTE PROCEDURE VIEWS' BEGIN DECLARE qStr TEXT DEFAULT ''; DECLARE queryStatement TEXT DEFAULT ''; DECLARE cursor_VAL VARCHAR(255) DEFAULT ''; DECLARE done INTEGER DEFAULT 0; DECLARE cursor_i CURSOR FOR SELECT DISTINCT CONCAT('empresa_homologacao_',(table_schema)) FROM information_schema.tables WHERE table_schema LIKE CONCAT('empresa_homologacao_',DB); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cursor_i; read_loop: LOOP FETCH cursor_i INTO cursor_VAL; IF done = 1 THEN LEAVE read_loop; END IF; SET qStr = ('SELECT CORPO DA VIEW'); END LOOP; CLOSE cursor_i; SET @qStr = CONCAT('USE empresa_homologacao_',DB,'; ','DROP VIEW IF EXISTS view_que_quero_criar; ', 'CREATE VIEW view_que_quero_criar AS ', qStr); SET @queryStatement=(SELECT @qStr); SELECT @queryStatement; PREPARE stmt FROM @queryStatement; EXECUTE stmt; DEALLOCATE PREPARE stmt; END$$ DELIMITER ;
E quando dei um "CALL" nela, com o codigo:
call CreateViewsVendas("teste");
Ela retornou:
USE empresa_homologacao_teste; DROP VIEW IF EXISTS view_que_quero_criar; CREATE VIEW view_que_quero_criar AS
Era isso que ela deveria retornar?
Eu tive que remover um monte de espaços que tinham no seu codigo, mas creio que seja pq você usou a citação ao invés da tag code do fórum.
Única coisa que eu troquei é o delimitador, pois // é pra função e não consegui executar para procedure, então tive que trocar para $$.
E dessa forma funcionou...
Espero ter ajudado. :D
GOSTEI 1