34

I need to clear all my inventory tables.

I've tried this:

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

But I get this error:

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

if this is the correct way, then what am I doing wrong?

David Moles
  • 39,436
  • 24
  • 121
  • 210
Luiscencio
  • 3,697
  • 13
  • 41
  • 73

12 Answers12

64

Use concat:

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

This will of course only generate SQL which you need to copy and run yourself.

mikeytown2
  • 1,636
  • 23
  • 37
ʞɔıu
  • 43,326
  • 30
  • 94
  • 142
  • ok so I copied the result, pasted it in the query browser, hit CtrlEnter and boooom!!!! nothing happended, tables still with data =( – Luiscencio Oct 15 '09 at 22:26
  • it seems that I have to execute each line in the query browser, well at least I don't have to write all the lines, just pres CtrlEnter on each one o.O – Luiscencio Oct 15 '09 at 22:36
  • must a function of your mysql client. ';' should work as a statement separator in most clients – ʞɔıu Oct 15 '09 at 22:48
  • 4
    You might also want to add `AND TABLE_SCHEMA = 'mydatabase'` to ensure you're only operating on a particular database. Also, adding `INTO OUTFILE 'c:\\script.sql'` will prevent you from having to copy & paste anything; instead, just run the script. – Rob Sobers Nov 10 '10 at 19:31
  • Little trick to have the whole query on 1 line : `SELECT group_concat(a.c SEPARATOR ' ') FROM (SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') AS c FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'inventory%') a;` – Thomas Ruiz Dec 12 '13 at 16:36
7

I know it's an older post already but maybe the following example is helpful for someone who needs to truncate multiple tables from linux command line or from within a shell script:

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>

Given that you need to replace the strings in brackets with your own values it was working for me. Also replace the 'your_table_a,your_table_b,your_table_c' with a comma-separated list of your tables. ;)

Matthias
  • 71
  • 1
  • 1
  • If you happen to need to flush all your cache tables because you setup a solution like memcache here's a useful command: mysql -uroot -proot --execute="SELECT concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME LIKE 'cache%'" | sed 1d | mysql -uroot -proot db_name ... just update the db_name and user credentials. – doublejosh Apr 23 '13 at 20:38
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;'
falperez
  • 101
  • 1
  • 1
  • This answer too will generate a string of SQL statements separated with ; But the key thing here is that it will turn of the foreign_key checks for you before truncating and later turn on the check again. This is needed if your tables have foreign_key pointing to each other. If you have a row in a table with a foreign_key to a table that you truncate you'll break the reference and mysql will throw an error. – MyGGaN Aug 09 '13 at 08:42
4

If you are using command line, you might want to try something like this.

mysql -u [user] -p[password] -e 'use [database]; show tables' | perl -lane 'print "truncate table $F[0]" if /^inventory/i' > [database].sql
kenorb
  • 118,428
  • 63
  • 588
  • 624
bichonfrise74
  • 1,547
  • 3
  • 14
  • 11
2

Here is a little improvement on the above SQL statement.

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

Notice the DISTINCT command in the beginning. This will make the SELECT result show only once the the tables that match your LIKE criteria.

Elias
  • 21
  • 1
1

If you have more than one database on your server, you may want to specify the db as well.

e.g. to clear Drupal cache tables

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

This results in sql like...

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

Giving two advantages,

  1. You can run this sql anywhere regardless of the currently selected database.
  2. You'll be sure that you're truncating the tables on the correct database.

See @falperez answer if foreign key checks get in the way of your mass truncate, (although of course they won't for drupal cache clearing)

chim
  • 7,655
  • 3
  • 44
  • 58
1

Try this statement, It will give you single line of all tables and you can copy that statements and run to execute all:

SELECT DISTINCT REPLACE(GROUP_CONCAT("TRUNCATE TABLE ", TABLE_NAME, ";"), ',', '')
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE "cache%";
kenorb
  • 118,428
  • 63
  • 588
  • 624
Ashwin Parmar
  • 2,942
  • 2
  • 21
  • 41
  • I like the idea. However mysql client is trimming the results, so it gets cut off. Anyone know how to prevent it from doing that? – Dave Cohen Jan 30 '14 at 18:29
  • The query is not working correctly. It returns table names like "cache_SOMETHING", where SOMETHING is a table, but cache_SOMETHING is not. – Dave Cohen Jan 30 '14 at 18:40
  • Replace `GROUP_CONCAT` with Only `CONCAT` function it will give you each `TRUNCATE TABLE TABLE_NAME;` in each row then you can copy each row and run it as you expect. So, now your MySQL Client will not trimming the results. – Ashwin Parmar Jan 31 '14 at 04:54
0
SELECT CONCAT('TRUNCATE TABLE ',TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'inventory%'

You should then take every row of the result set and call it as the SQL statement. You can do it by coping and pasting the separated results to the command window.

But much better solution is to write some program which will make the query above and loop through the results and make every query.

Use PHP for that or any other scripting language. Many examples even here on SO.

Lukasz Lysik
  • 10,012
  • 3
  • 46
  • 68
0
SELECT REPLACE(GROUP_CONCAT("TRUNCATE TABLE ", TABLE_NAME, ";"), ',', '') 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE "cache%";

This is based on AshwinP's answer. I had to remove DISTINCT and add WHERE TABLE_SCHEMA=DATABASE() for it to work for me.

The command does not truncate tables, but returns a one-liner that will. Copy and paste the one-liner into the mysql client.

Dave Cohen
  • 1,217
  • 1
  • 15
  • 21
0

Late answer... But better later, than never. To avoid unnecessary copying and pasting or additional shell scripting, the most agnostic approach -- at least with respect to MySQL and MariaDB -- to truncating a set of tables in a database or matching a pattern is via a stored procedure.

The following is a script used regularly to truncate all tables in the current database. The SELECT statement can be tailored to match patterns if more precise control is required.

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;

This example drops the store procedure after it is used. However, if this is a regular task, then it is better to just add it once by running everything before the $$ delimiter and executing

CALL truncate_tables();

on the target database.

Frelling
  • 2,686
  • 20
  • 24
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 

..this worked for me.. replace user, pass and db with your own.

Gopal
  • 1
-1

very nice example of generating and executing statements USING concat I just read minute ago:

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;
Pavel Zendulo
  • 59
  • 1
  • 5
  • It's not possible to run multiple statements in one prepared statement according to: http://stackoverflow.com/questions/20371677/execute-multiple-semi-colon-seperated-query-using-mysql-prepared-statement – Jamie Novick - Compucorp Nov 29 '16 at 03:53
  • The above script works for ``DROP TABLE`` since it can accept multiple table names. The same is not true for ``TRUNCATE``. – Frelling Sep 17 '18 at 14:44