paolo@bimodesign.com | +34 608 61 64 10

DB Relational

        

MySQL - Prepare in una Procedure

In questo articolo illustro come sia possibile eseguire delle select che presentano dei parametri, attraverso delle Stored Procedure in MySql. Le select sono archivate nella base dati, ma potrebbero essere chiaramente presenti su file o in altre variabili.
Prima di leggere l'articolo, occorre aver gia' familiarizzato con le Stored Procedure in MySql e per questo vi consiglio una ottima lettura presente a questo link (e a quelli presenti nella pagina) Tutorial Storage Procedure

In un campo di una tabella di tipo MEDIUMTEXT ho, per ogni record, archivato una istruzione sql di questo tipo

select count(*) into @iTotal from aa;

La tabella sara' di questo tipo (inserisco anche tutte le altre istruzioni, uguali alla precedente

CREATE TABLE  report_detalle (
  idreportdetalle int(11) NOT NULL AUTO_INCREMENT,
  description varchar(50) NOT NULL,
  statment mediumtext NOT NULL,
  execute char(1) NOT NULL,
  PRIMARY KEY (idreportdetalle)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

INSERT INTO report_detalle VALUES  
 (1,'aa','select count(*) into @iTotal from aa;','S'),
 (2,'bb','select count(*) into @iTotal from bb;','N'),
 (3,'cc','select count(*) into @iTotal from cc;','S');

Potete notare l'uso del @ come ritorno della variabile iTotal
Mentre la stored procedure sara' cosi'

delimiter $$
    DROP PROCEDURE IF EXISTS admin_report$$

CREATE PROCEDURE admin_report()
        BEGIN
            DECLARE iIdReport INTEGER (11) UNSIGNED;
            DECLARE iIdReportDetalle INTEGER (11) UNSIGNED;
            DECLARE dValueTotal DECIMAL (10,2) UNSIGNED;
            DECLARE iTimeExecute INTEGER (11) UNSIGNED;
            DECLARE sStatment MEDIUMTEXT;
	    DECLARE done INT DEFAULT FALSE;
            
            DECLARE cursorReportDetalle CURSOR FOR
                SELECT `idreportdetalle`, 
                       `statment` 
                  FROM `report_detalle`
                 WHERE `execute`='S';

            DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

            OPEN cursorReportDetalle;

            read_loop: LOOP
                FETCH cursorReportDetalle INTO iIdReportDetalle,sStatment;

		IF done THEN
		      LEAVE read_loop;
		END IF;

		SET @s = sStatment;
		PREPARE stmt FROM @s;
	        EXECUTE stmt;

                INSERT INTO `report_data` (`idreport`, `idreportdetalle` , `value`,`time_execute`) 
                     VALUES ('1', iIdReportDetalle, @iTotal,'12233');

            END LOOP;

            CLOSE cursorReportDetalle;

        END$$
delimiter ;

Notate in particolare questa parte di codice

SET @s = sStatment;
PREPARE stmt FROM @s;
EXECUTE stmt;

INSERT INTO `report_data` (`idreport`, `idreportdetalle` , `value`,`time_execute`) 
       VALUES ('1', iIdReportDetalle, @iTotal,'12233');

- Assegno alla variabile s l'istruzione estratta dal cursore.
- Quindi eseguo la PREPARE
- Lancio l'EXECUTE
- Usero' la variabile iTotal, definita nell'istruzione nella tabella, come valore da inserire.