Procedimento armazenado que automaticamente excluir linhas com mais de 7 dias no MYSQL

Gostaria de saber se é possível criar um procedimento armazenado que automaticamente, todos os dias às 00:00, exclui todas as linhas de todas as tabelas com mais de 7 dias.

Tenho visto poucas soluções, mas não tenho certeza se é o que estou procurando, e seria bom se alguém tivesse algum bom exemplo. Eu sei que isso poderia ser feito com scripts simples em python e php, mas eu gostaria de algo mais automatizado pelo MySQL.

Qualquer ajuda seria realmente aprecio.

Obrigado!

    O Mysql tem sua funcionalidade EVENT para evitar interações cron complicadas quando muito do que você está planejando é relacionado ao sql e menos relacionado a arquivos. Veja a página do manual aqui . Espero que o texto abaixo seja lido como uma rápida visão geral dos passos importantes e coisas a serem consideradas, e testes verificáveis ​​também.

     show variables where variable_name='event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | OFF | +-----------------+-------+ 

    ooops, o agendador de events não está ativado. Nada será ativado.

    SET GLOBAL event_scheduler = ON; -- turn her on and confirm below

     show variables where variable_name='event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+ 

    Esquema para teste

     create table theMessages ( id int auto_increment primary key, userId int not null, message varchar(255) not null, updateDt datetime not null, key(updateDt) -- FK's not shown ); -- it is currently 2015-09-10 13:12:00 -- truncate table theMessages; insert theMessages(userId,message,updateDt) values (1,'I need to go now, no followup questions','2015-08-24 11:10:09'); insert theMessages(userId,message,updateDt) values (7,'You always say that ... just hiding','2015-08-29'); insert theMessages(userId,message,updateDt) values (1,'7 day test1','2015-09-03 12:00:00'); insert theMessages(userId,message,updateDt) values (1,'7 day test2','2015-09-03 14:00:00'); 

    Crie 2 events, 1º é executado diariamente, 2º é executado a cada 10 minutos

    Ignore o que eles estão realmente fazendo (jogando um contra o outro). O ponto é sobre abordagens de time difference e agendamento .

     DELIMITER $$ CREATE EVENT `delete7DayOldMessages` ON SCHEDULE EVERY 1 DAY STARTS '2015-09-01 00:00:00' ON COMPLETION PRESERVE DO BEGIN delete from theMessages where datediff(now(),updateDt)>6; -- not terribly exact, yesterday but <24hrs is still 1 day -- etc etc all your stuff in here END;$$ DELIMITER ; 

    ...

     DELIMITER $$ CREATE EVENT `Every_10_Minutes_Cleanup` ON SCHEDULE EVERY 10 MINUTE STARTS '2015-09-01 00:00:00' ON COMPLETION PRESERVE DO BEGIN delete from theMessages where TIMESTAMPDIFF(HOUR, updateDt, now())>168; -- messages over 1 week old (168 hours) -- etc etc all your stuff in here END;$$ DELIMITER ; 

    Mostrar status de events (diferentes abordagens)

     show events from so_gibberish; -- list all events by schema name (db name) show events; -- < --------- from workbench / sqlyog show events\G;` -- <--------- I like this one from mysql> prompt *************************** 1. row *************************** Db: so_gibberish Name: delete7DayOldMessages Definer: root@localhost Time zone: SYSTEM Type: RECURRING Execute at: NULL Interval value: 1 Interval field: DAY Starts: 2015-09-01 00:00:00 Ends: NULL Status: ENABLED Originator: 1 character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: utf8_general_ci *************************** 2. row *************************** Db: so_gibberish Name: Every_10_Minutes_Cleanup Definer: root@localhost Time zone: SYSTEM Type: RECURRING Execute at: NULL Interval value: 10 Interval field: MINUTE Starts: 2015-09-01 00:00:00 Ends: NULL Status: ENABLED Originator: 1 character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: utf8_general_ci 2 rows in set (0.06 sec) 

    Coisas aleatórias a considerar

    drop event someEventName; - < ----- uma coisa boa para saber sobre

    não pode alias datediff e usar em where cláusula em 1 linha, então

     select id,DATEDIFF(now(),updateDt) from theMessages where datediff(now(),updateDt)>6; 

    fique mais exato, 168 horas para uma semana de idade

     select id,TIMESTAMPDIFF(HOUR, updateDt, now()) as `difference` FROM theMessages; +----+------------+ | id | difference | +----+------------+ | 1 | 410 | | 2 | 301 | | 3 | 169 | | 4 | 167 | +----+------------+ 

    O link para a Página Manual mostra um pouco de flexibilidade com opções de intervalo, mostradas abaixo:

    intervalo:

     quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND} 

    concurrency

    Incorpore quaisquer medidas de simultaneidade necessárias para que vários events (ou vários disparos do mesmo evento) não causem ataques a dados.

    Definir e esquecer

    Lembre-se, por enquanto, porque você vai esquecer, que esses events continuam sendo triggersdos. Portanto, construa um código sólido que continue funcionando, mesmo quando você esquecer. Qual você provavelmente irá.

    Suas necessidades particulares

    Você precisa determinar quais linhas precisam ser excluídas primeiro por tabela, de forma que ela respeite as restrições da chave primária. Apenas coloque todos na ordem correta dentro da área óbvia, através da instrução CREATE EVENT, que pode ser massiva.

    Você pode usar o procedimento armazenado abaixo e programá-lo por crontab ou por events.

    Nota: Basta alterar mydb com seu database, quais dados da tabela de database você deseja excluir e testar primeiro no ambiente de teste.

     DELIMITER $$ USE `mydb`$$ DROP PROCEDURE IF EXISTS `sp_delete`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_delete`() BEGIN DECLARE done INT(1) DEFAULT 0; DECLARE _tbl VARCHAR(100) DEFAULT ''; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=done; DECLARE cur1 CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema='mydb' AND table_type='base table'; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=done; OPEN cur1; REPEAT FETCH cur1 INTO _tbl; IF _db = '' THEN SET done = 1; END IF; IF (done<>1) THEN SET @str=CONCAT("delete from ",_tbl," where updateon < SUBDATE(CURDATE(),INTERVAL 7 DAY)"); PREPARE stmt FROM @str; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; UNTIL done END REPEAT; CLOSE cur1; SELECT 'done'; END$$ DELIMITER ;