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

时间:2009-10-15 22:11:24

标签: sql mysql

我需要清除所有库存表。

我试过这个:

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

但是我收到了这个错误:

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

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

12 个答案:

答案 0 :(得分:59)

使用concat:

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

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

答案 1 :(得分:7)

我知道它已经是一个较旧的帖子但是以下示例对于需要从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'替换为以逗号分隔的表格列表。 ;)

答案 2 :(得分:6)

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;'

答案 3 :(得分:4)

如果您使用的是命令行,则可能需要尝试这样的操作。

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

答案 4 :(得分:2)

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

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

在开头注意DISTINCT命令。这将使SELECT结果只显示符合LIKE标准的表格。

答案 5 :(得分:1)

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

e.g。清除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. 你会确定你正在截断表格 正确的数据库。
  3. 如果外键检查妨碍了大量截断,请参阅@falperez答案(当然,它们不会用于drupal缓存清除)

答案 6 :(得分:1)

尝试这个语句,它将为您提供所有表的单行,您可以复制该语句并运行以执行所有语句:

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

答案 7 :(得分:0)

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

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

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

将PHP用于该语言或任何其他脚本语言。很多例子甚至都在SO上。

答案 8 :(得分:0)

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客户端。

答案 9 :(得分:0)

最新答案...但是以后总比没有好。为了避免不必要的复制和粘贴或其他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();

在目标数据库上。

答案 10 :(得分:0)

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 

..这对我有用。.用自己的用户替换 user pass db

答案 11 :(得分:-1)

生成和执行语句的非常好的例子使用我刚刚读过的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;