我一直在研究如何尝试从查询结果中获取所有行并单独处理它们。我写了一个脚本,我认为它可以工作,但显然不是。
剧本:
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
该脚本旨在删除超过30天的所有表。虽然它似乎不适用于MySQL版本5.5.37。
我是MySQL新手,我正在使用MySQL for Windows(XP)运行服务器。对于相应的服务器版本,CURSORS的这种语法可能不正确吗?我不确定,但如果有人能帮助我,我会很高兴。
修改
这是我尝试从SQL命令行执行脚本时返回的错误消息:
错误1064(42000):您的SQL语法出错;
检查与您的MySQL服务器版本对应的手册,以便在第1行的'DECLARE @name char(20)'附近使用正确的语法
错误1064(42000):您的SQL语法出错;
检查与您的MySQL服务器版本对应的手册,以便在附近使用正确的语法 'DEC_阅读c1 CURSOR READ_ONLY 对于 SELECT table_name 来自第1行的information_schema.tables'
错误1064(42000):您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以便在附近使用正确的语法 '取 下一步来自c1 INTO @table_name
WHILE @@ FETCH_STATUS = 0 BEGIN
在第1行预备st'
更新
我也试过这个脚本(注意:我打算创建一个事件,每天执行一次以删除超过30天的表。):
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 ;
在SQL命令行中运行此脚本将返回:
错误1064(42000):您的SQL语法出错;
检查与您的MySQL服务器版本对应的手册,以便在附近使用正确的语法 '@name char(20); DECLARE c1 CURSOR READ_ONLY 对于 SELECT table_name 来自infor'第5行
答案 0 :(得分:1)
尝试以下程序:
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 ;