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?
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.
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. ;)
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;'
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
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.
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,
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)
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.
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%";
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.
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.