web-dev-qa-db-fra.com

Tronquer toutes les tables de la base de données MySQL qui correspondent à un modèle de nom

Je dois effacer toutes mes tables d'inventaire.

J'ai essayé ceci:

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

Mais je reçois cette erreur:

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

si c'est la bonne façon, alors qu'est-ce que je fais mal?

33
Luiscencio

Utilisez concat:

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

Cela ne générera bien sûr que du code SQL que vous devez copier et exécuter vous-même.

57
ʞɔıu

Je sais que c'est déjà un article plus ancien, mais l'exemple suivant est peut-être utile pour quelqu'un qui doit tronquer plusieurs tables à partir de la ligne de commande linux ou d'un script 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>

Étant donné que vous devez remplacer les chaînes entre parenthèses par vos propres valeurs, cela fonctionnait pour moi. Remplacez également les éléments "votre_table_a, votre_table_b, votre_table_c" par une liste de vos tables séparées par des virgules. ;)

7
Matthias
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;'
6
falperez

Si vous utilisez la ligne de commande, vous voudrez peut-être essayer quelque chose comme ceci.

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

Voici une petite amélioration par rapport à l’instruction SQL ci-dessus.

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

Notez la commande DISTINCT au début. Cela fera que le résultat de SELECT n’affiche qu’une fois les tables correspondant à vos critères LIKE.

2
Elias

Si vous avez plusieurs bases de données sur votre serveur, vous pouvez également spécifier la base de données.

par exemple. effacer les tables de cache Drupal

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

Cela se traduit par sql comme ...

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

Donner deux avantages, 

  1. Vous pouvez exécuter ce SQL n'importe où, quelle que soit la base de données Actuellement sélectionnée.
  2. Vous serez sûr de tronquer les tables de la base de données Correcte.

Voir la réponse de @falperez si les contrôles de clé étrangère gênent votre troncature en masse (bien que cela ne soit évidemment pas le cas pour l'effacement du cache drupal)

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

Vous devez ensuite prendre chaque ligne du jeu de résultats et l'appeler en tant qu'instruction SQL. Vous pouvez le faire en copiant et collant les résultats séparés dans la fenêtre de commande. 

Mais la meilleure solution consiste à écrire un programme qui fera la requête ci-dessus, à parcourir les résultats et à rendre chaque requête.

Utilisez PHP pour cela ou tout autre langage de script. De nombreux exemples, même ici sur SO.

0
Lukasz Lysik

Essayez cette instruction, elle vous donnera une seule ligne de toutes les tables et vous pouvez copier ces instructions et les exécuter pour toutes les exécuter:

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

Réponse tardive ... Mais mieux vaut plus tard que jamais. Pour éviter des copier-coller inutiles ou des scripts Shell supplémentaires, l'approche la plus agnostique - du moins en ce qui concerne MySQL et MariaDB - pour tronquer un ensemble de tables dans une base de données ou faire correspondre un modèle consiste à utiliser une procédure stockée.

Ce qui suit est un script utilisé régulièrement pour tronquer toutes les tables de la base de données actuelle. La déclaration SELECT peut être adaptée pour faire correspondre les modèles si un contrôle plus précis est requis.

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;

Cet exemple supprime la procédure de stockage après son utilisation. Toutefois, s’il s’agit d’une tâche normale, il est préférable de l’ajouter une fois en exécutant tout ce qui précède le délimiteur $$ et en exécutant

CALL truncate_tables();

sur la base de données cible.

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

Ceci est basé sur la réponse d'AshwinP. Je devais supprimer DISTINCT et ajouter WHERE TABLE_SCHEMA = DATABASE () pour que cela fonctionne pour moi.

La commande ne tronque pas les tables, mais renvoie une ligne qui le fera. Copiez et collez le one-liner dans le client mysql.

0
Dave Cohen