【问题标题】:SQL MariaDB - Loop this query for every table in every database with exceptionsSQL MariaDB - 为每个数据库中的每个表循环此查询,但有例外
【发布时间】:2018-11-30 03:20:38
【问题描述】:

我有大型数据库,每月使用以下查询进行修剪。但是,我有数百个表,并希望将其变成数据库中每个表的 foreach 循环。

我知道如何在 PHP 中实现这个循环,但如果能在纯 SQL 中直接作为数据库查询运行,那就太好了。

noprune为前缀的表,例如noprune_master_tableZ需要被排除在循环之外。

我从哪里开始?谢谢

START TRANSACTION;
set @N := (now());
CREATE TABLE master_tableA_snapshot AS SELECT * FROM master_tableA where insertDATE < date_sub(@N,INTERVAL 32 DAY);
SELECT * from master_tableA_snapshot INTO OUTFILE '/tmp/master_tableA_snapshot_TODAYSDATE.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
DELETE from master_tableA where insertDATE < date_sub(@N,INTERVAL 32 DAY);
DROP TABLE master_tableA_snapshot;
COMMIT;

【问题讨论】:

  • DROP TABLE 这样的DDL 语句是一个显式的COMMIT,所以你的事务没有做太多。你想让它做什么?为什么不直接SELECT .. INTO OUTFILE 而不是临时表? PHP 非常擅长编写脚本,而它可以放入 MySQL 事件中,但更难调试和维护。
  • 嗨,Dan,我想是因为我经常写入 master_tableA,所以我不得不将这一切都包装在一个事务中?我将在 SELECT 命令期间插入 master_tableA
  • 事务更多的是一次提交多个事情。我假设您没有插入 32 天以上的日期。所以它不会有所作为。在可重复读取隔离级别(默认)下也不会产生影响,因为DELETE 语句将看到与SELECT 看到的完全相同的数据。

标签: mysql sql mariadb innodb


【解决方案1】:

您实际上只有两个带有辅助变量的语句,简化为:

set @N := date_sub(NOW(),INTERVAL 32 DAY);

SELECT *
FROM master_tableA
WHERE insertDATE < @N
INTO OUTFILE '/tmp/master_tableA_snapshot_TODAYSDATE.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

DELETE from master_tableA where insertDATE < @N;

PHP 通过查询选择表名:

SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE SCHEMA='mydatabase'
  AND TABLE_NAME NOT LIKE 'noprune%';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多