临时表和行及其名称的事件调度器

iq3niunx  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(433)

我有一个数据库和以下表格:temp\u 1,temp\u 2。。。。和你的任务。在cached\u tbl中,我有列表名称,在相应的行中,我存储了上面提到的所有临时表名称。所以我想做的是创建一个事件调度器来删除一天前创建的临时表…为此我写了

SELECT (DROP) 
    *
FROM
    information_schema.TABLES
WHERE 
    table_schema = 'db' and CREATE_TIME < (NOW()-INTERVAL 24 HOUR)

但是我还想删除缓存的表中包含刚刚删除的表名的行。。。请告诉我怎么做。。。在常规编程中,我只需将上一个脚本中所有选定的表名放入数组中,并通过循环将此表名与缓存的表名进行比较。。。但是我不知道如何在mysql中实现它

5w9g7ksd

5w9g7ksd1#

嗨,欢迎来到so。
回答你的问题-你不应该这样做(查看临时表格列表等)。一般来说,临时表只为当前连接(会话)服务,当您关闭一个临时表时,所有临时表都将消失。这很正常。临时表应该为您的逻辑提供某种额外的缓存—例如,当您需要将结果从一个过程导出到另一个过程时。
但您需要记住,sql用于数据的持久存储和管理,如果您想存储数据,请使用普通表,其余的由mysql来完成。使用触发器或存储过程检查/刷新表中的数据。
更具体地说临时表的名称。检查手册-https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-temp-table-info.html -您将看到mysql自己存储临时表的名称

CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB;

SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\G

***************************1. row***************************

            TABLE_ID: 194
                NAME: #sql7a79_1_0
              N_COLS: 4
               SPACE: 182
PER_TABLE_TABLESPACE: FALSE
       IS_COMPRESSED: FALSE

它不是t1表,而是#sql7a79ŧU 1ŧU 0。你可以说-等等,我知道那张table的名字是t1!-但是您应该记住,t1只是您在当前会话中使用的某种指针,而且您有自己的目的,mysql依赖于自己的机制。

1mrurvl1

1mrurvl12#

alisa,我假设您正在使用命名约定temp_1,temp_2来表示您打算在很短时间后删除这些表,并且这些表不是@anton推测的临时表。
需要注意的几点ab:请举例说明:
它是作为一个事件编写的,但是您可以很容易地将它转换成一个过程,允许您传入不同的间隔值或数据库名称。
您将需要使用游标来获取表名,使用动态sql来准备和执行语句来删除表并删除表中的记录 cached_tbl .
我已经做了一个比严格必要的复杂一点的例子来说明如何在一个语句中创建和填充一个临时表,如果你把它变成一个过程的话,这将是非常有用的。您可以通过将游标声明为@sql1中的语句并删除stmt1上的prepare和execute来简化它。
您可能希望在选择表时限制得更严格一点,否则会有删除表的风险 cached_tbl 或其他数据库表。

DELIMITER //

CREATE EVENT prune
ON SCHEDULE
  EVERY 1 DAY
DO

  BEGIN
    DECLARE done BOOLEAN DEFAULT FALSE;
    DECLARE tname VARCHAR(64);
    DECLARE cur CURSOR FOR SELECT * FROM `tables_tmp`;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    SET @sql1 = 
      'CREATE TEMPORARY TABLE `tables_tmp`  
       SELECT `table_schema`,`table_name`  
       FROM `information_schema`.`tables`
       WHERE `table_schema` = ''db''
       AND `table_name` LIKE ''temp_%'' 
       AND `create_time` < (NOW() - INTERVAL 1 DAY)';

    PREPARE stmt1 FROM @sql1;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    OPEN cur;

    myloop:LOOP
      FETCH cur INTO tname;

      IF done = TRUE THEN
        LEAVE myloop;
      END IF;

      SET @sql2 = CONCAT('DROP TABLE IF EXISTS `db`.`', tname , '`;'); 
      PREPARE stmt2 FROM @sql2;
      EXECUTE stmt2;
      DEALLOCATE PREPARE stmt2;

      SET @sql3 = CONCAT('DELETE FROM `cached_tbl` WHERE `table_name` = ''', tname , ''';'); 
      PREPARE stmt3 FROM @sql3;
      EXECUTE stmt3;
      DEALLOCATE PREPARE stmt3;

    END LOOP;

  END //

DELIMITER ;

相关问题