Domanda

Sto cercando di cercare di trovare un modo per recuperare tutte le righe da un risultato di query ed elaborarli individualmente. Ho scritto una sceneggiatura che pensavo avrebbe funzionato ma apparentemente no.

Lo script:

DECLARE @name char(20);

DECLARE c1 CURSOR READ_ONLY
FOR
SELECT table_name
FROM information_schema.tables WHERE table_schema = 'puslogger' AND UPDATE_TIME < (now() - interval 30 day)

OPEN c1; 

FETCH NEXT FROM c1
INTO @table_name

WHILE @@FETCH_STATUS = 0
BEGIN

PREPARE stmt FROM "concat('DROP TABLE IF EXISTS `', @table_name,'`;')"
EXECUTE stmt
DEALLOCTATE stmt

FETCH NEXT FROM c1
INTO @table_name

END

CLOSE c1
DEALLOCATE c1
.

Lo script ha lo scopo di far cadere tutte le tabelle di età superiore a 30 giorni. Anche se non sembra funzionare per MySQL versione 5.5.37.

Sono nuovo a Mysql e sto eseguendo un server con MySQL per Windows (XP). Forse questa sintassi per i cursori non è corretta per la versione del server corrispondente? Non sono sicuro ma sarei molto felice se qualcuno potesse aiutarmi.

Modifica:

Questo è il messaggio di errore restituito quando provo ad eseguire lo script dalla riga di comando SQL:

.

Errore 1064 (42000): si ha un errore nella sintassi SQL;

Controllare il manuale che corrisponde alla versione del server MySQL per la giusta sintassi da utilizzare vicino a 'dichiarare @name char (20)' alla linea 1

Errore 1064 (42000): si ha un errore nella sintassi SQL;

Controllare il manuale che corrisponde alla versione MySQL Server per la sintassi giusta da utilizzare vicino 'Dichiarare il cursore C1 read_only PER Seleziona Table_Name. Da informazioni_schema.tables 'at Line 1

Errore 1064 (42000): si ha un errore nella sintassi SQL; Controllare il manuale corrispondente alla versione MySQL Server per la giusta sintassi da utilizzare vicino 'Recupero Avanti da C1. In @table_name

while @@ fetch_status= 0 Inizia

Preparare ST 'alla linea 1

Aggiornamento:

Ho anche provato questo script (nota: intendo creare un evento che verrà eseguito quotidianamente per rimuovere le tabelle di età superiore a 30 giorni.):

delimiter |

CREATE EVENT clean_logger
    ON SCHEDULE EVERY 1 DAY
    DO
    BEGIN
        DECLARE @name char(20);
    DECLARE c1 CURSOR READ_ONLY
    FOR
    SELECT table_name
    FROM information_schema.tables WHERE table_schema = 'puslogger' AND UPDATE_TIME < (now() - interval 30 day);

    OPEN c1; 

    FETCH NEXT FROM c1
    INTO @table_name;

    WHILE @@FETCH_STATUS = 0
    BEGIN

    PREPARE stmt FROM "concat('DROP TABLE IF EXISTS `', @table_name,'`;')";
    EXECUTE stmt;
    DEALLOCTATE stmt;

    FETCH NEXT FROM c1
    INTO @table_name;

    END;

CLOSE c1;
DEALLOCATE c1;
END |

delimiter ;
.

L'esecuzione di questo script nella riga di comando SQL ritorna:

.

Errore 1064 (42000): si ha un errore nella sintassi SQL;

Controllare il manuale che corrisponde alla versione MySQL Server per la sintassi giusta da utilizzare vicino '@name char (20); Dichiarare il cursore C1 read_only PER Seleziona Table_Name. Da Infors 'at Line 5

È stato utile?

Soluzione

Prova sotto Procedura:

DELIMITER $$

USE `test`$$

DROP PROCEDURE IF EXISTS `sp_drop_table`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_drop_table`()
BEGIN
        DECLARE done INT(1) DEFAULT 0;
        DECLARE _tblname VARCHAR(20) DEFAULT '';

        DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = 'puslogger' AND UPDATE_TIME < (NOW() - INTERVAL 30 DAY);
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
-- open cursor1
OPEN cur1;
BEGIN

REPEAT
FETCH cur1 INTO _tblname;
IF _tblname = '' THEN
    SET done = 1;
END IF; 

            IF (done<>1) THEN
    SET @str1=CONCAT("DROP TABLE IF EXISTS ",_tblname);
                 PREPARE stmt1 FROM @str1;
                 EXECUTE stmt1;
                 DEALLOCATE PREPARE stmt1;

            END IF;

UNTIL done
END REPEAT;
END;
     CLOSE cur1;
-- close cursor1     

     SELECT 'done';

END$$

DELIMITER ;
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top