繁体   English   中英

截断 MySQL 数据库中与名称模式匹配的所有表

[英]Truncate all tables in MySQL database that match a name pattern

我需要清除我所有的库存表。

我试过这个:

SELECT 'TRUNCATE TABLE ' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'inventory%'

但我收到此错误:

Truncated incorrect DOUBLE value: 'TRUNCATE TABLE ' Error Code 1292

如果这是正确的方法,那么我做错了什么?

使用连接:

SELECT concat('TRUNCATE TABLE `', TABLE_NAME, '`;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'inventory%'

这当然只会生成您需要自己复制和运行的 SQL。

我知道这已经是一篇较旧的帖子了,但也许以下示例对需要从 linux 命令行或 shell 脚本中截断多个表的人有所帮助:

mysql -p<secret> --execute="SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '<database>' AND FIND_IN_SET(TABLE_NAME,'your_table_a,your_table_b,your_table_c')" | sed 1d | mysql -p<secret> <database>

鉴于您需要用您自己的值替换括号中的字符串,它对我有用。 还要用逗号分隔的表格列表替换“your_table_a,your_table_b,your_table_c”。 ;)

SELECT 'SET FOREIGN_KEY_CHECKS = 0;'
UNION
SELECT DISTINCT concat( "TRUNCATE TABLE ", TABLE_NAME, ";" )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mydbname'
UNION
SELECT 'SET FOREIGN_KEY_CHECKS = 1;'

如果您使用命令行,您可能想尝试这样的操作。

mysql -u [user] -p[password] -e 'use [database]; show tables' | perl -lane 'print "truncate table $F[0]" if /^inventory/i' > [database].sql

这里是对上述SQL语句的一点改进。

SELECT DISTINCT concat("TRUNCATE TABLE ", TABLE_NAME, ";") 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE "cache%"

注意开头的 DISTINCT 命令。 这将使 SELECT 结果仅显示一次与您的 LIKE 条件匹配的表。

如果您的服务器上有多个数据库,您可能还需要指定 db。

例如清除 Drupal 缓存表

SELECT DISTINCT CONCAT(  
    "TRUNCATE TABLE ", 
    TABLE_SCHEMA,  
    ".",
    TABLE_NAME, 
    ";" ) 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE  "cache_%"
AND TABLE_SCHEMA = 'dbname';

这会导致 sql 像...

TRUNCATE TABLE dbname.cache_admin_menu;
TRUNCATE TABLE dbname.cache_block;
etc.

提供两个优势,

  1. 无论当前选择的数据库如何,您都可以在任何地方运行此 sql。
  2. 您将确定您正在截断正确数据库中的表。

如果外键检查妨碍了您的大规模截断,请参阅@falperez 的答案(尽管它们当然不会用于清除 drupal 缓存)

试试这个语句,它会给你所有表的一行,你可以复制该语句并运行以执行所有:

SELECT DISTINCT REPLACE(GROUP_CONCAT("TRUNCATE TABLE ", TABLE_NAME, ";"), ',', '')
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE "cache%";
SELECT CONCAT('TRUNCATE TABLE ',TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'inventory%'

然后,您应该获取结果集的每一行并将其作为 SQL 语句调用。 您可以通过将分离的结果复制并粘贴到命令窗口来实现。

但是更好的解决方案是编写一些程序来进行上面的查询并遍历结果并进行每个查询。

使用 PHP 或任何其他脚本语言。 许多例子甚至在这里。

SELECT REPLACE(GROUP_CONCAT("TRUNCATE TABLE ", TABLE_NAME, ";"), ',', '') 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE "cache%";

这是基于 AshwinP 的回答。 我必须删除 DISTINCT 并添加 WHERE TABLE_SCHEMA=DATABASE() 才能为我工作。

该命令不会截断表,但会返回一个单行。 将单行复制粘贴到mysql客户端。

迟到的答案......但迟到总比没有好。 为了避免不必要的复制和粘贴或额外的 shell 脚本,最不可知的方法——至少对于 MySQL 和 MariaDB——截断数据库中的一组表或匹配模式是通过存储过程。

下面是一个经常用来截断当前数据库中所有表的脚本。 如果需要更精确的控制,可以定制SELECT语句以匹配模式。

DROP PROCEDURE IF EXISTS truncate_tables;

DELIMITER $$
CREATE PROCEDURE truncate_tables()
BEGIN
  DECLARE tblName CHAR(64);
  DECLARE done INT DEFAULT FALSE;
  DECLARE dbTables CURSOR FOR
    SELECT table_name
    FROM information_schema.tables
    WHERE table_schema = (SELECT DATABASE());
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN dbTables;
  SET FOREIGN_KEY_CHECKS = 0;

  read_loop: LOOP
    FETCH dbTables INTO tblName;
    IF done THEN
      LEAVE read_loop;
    END IF;

    PREPARE stmt FROM CONCAT('TRUNCATE ', tblName);
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END LOOP read_loop;

  CLOSE dbTables;
  SET FOREIGN_KEY_CHECKS = 1;
END
$$

CALL truncate_tables();
DROP PROCEDURE IF EXISTS truncate_tables;

此示例在使用后删除存储过程。 但是,如果这是一个常规任务,那么最好通过在$$分隔符之前运行所有内容并执行

CALL truncate_tables();

在目标数据库上。

mysql -uuser -ppass --execute="SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME LIKE 'cache%'" | sed 1d | mysql -uuser -ppass db 

..这对我有用..用你自己的替换userpassdb

使用 concat 生成和执行语句的非常好的示例我刚刚读过:

http://www.mysqltutorial.org/mysql-drop-table

-- set table schema and pattern matching for tables

SET @schema = 'classicmodels';
SET @pattern = 'test%';

-- build dynamic sql (DROP TABLE tbl1, tbl2...;)

SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(@schema,'.',table_name)),';')
INTO @droplike FROM information_schema.tables WHERE @schema = database()
AND table_name LIKE @pattern;

-- display the dynamic sql statement

SELECT @droplike;  

-- execute dynamic sql

PREPARE stmt FROM @dropcmd;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM