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:
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:
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
Alex William
Responder
Gostei + 1
Clique aqui para fazer login e interagir na Comunidade :)