MYSQL - Procedure para criação de views

SQL

MySQL

Amazon Web Services - AWS

10/11/2020

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:

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

Chromusmaster

Curtidas 0

Melhor post

Alex William

Alex William

17/11/2020

Olá amigo, tudo bem?

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
POSTAR