Fórum MYSQL - Procedure para criação de views #613235
10/11/2020
0
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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
Curtir tópico
+ 0
Responder
Post mais votado
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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:
1 | call CreateViewsVendas( "teste" ); |
Ela retornou:
1 | 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
Alex William

Responder
Gostei + 1
Clique aqui para fazer login e interagir na Comunidade :)