web-dev-qa-db-fra.com

Comment puis-je supprimer tous les déclencheurs d'une base de données MySQL à l'aide d'une seule instruction SQL?

J'ai une base de données que j'ai clonée, et maintenant tous les déclencheurs de journalisation pointent vers des tables de journal dans le schéma d'origine. Je dois les supprimer tous en une seule fois (il y en a plusieurs dizaines) afin de pouvoir les recréer. Comment cela peut-il être fait avec une seule commande?

29
Matt Gibson

C'est une vieille question, mais comme c'est celle qui revient sans cesse dans mes recherches, j'ai pensé publier une solution ici. Dans mon cas, j'avais besoin de créer un seul fichier contenant un mysqldump complet, puis de supprimer tous les déclencheurs, puis de les ajouter à nouveau. J'ai pu le faire en utilisant la commande suivante pour ajouter le DROP TRIGGER instructions à mon vidage avant d'ajouter le vidage des déclencheurs.

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' >> dump.sql

Pour supprimer tous les déclencheurs dans la même commande (comme mentionné par @Stephen Crosby dans les commentaires), vous pouvez simplement rediriger cela dans MySQL comme suit:

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | mysql -u [db user] -p[db password] [db name]
28
Justin Warkentin
SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM  information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';

Copiez et collez le sql généré

Si vous devez supprimer tous les déclencheurs de toutes les bases de données, assurez-vous de filtrer le schéma mysql.

SELECT Concat('DROP TRIGGER ', EVENT_OBJECT_SCHEMA, '.', Trigger_Name, ';'), TRIGGER_NAME, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE FROM  information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA <> 'mysql';
36
Lücks

Malheureusement, cela n'est pas possible dans une instruction SQL régulière ou une procédure stockée.

Solution

La solution la plus simple pour supprimer tous les déclencheurs peut être un script bash:

echo "select concat('drop trigger ', trigger_name, ';')
  from information_schema.triggers where trigger_schema = 'your_database'" |
  mysql --defaults-extra-file=.mysql.conf --disable-column-names | 
  mysql --defaults-extra-file=.mysql.conf

Cela nécessite un fichier d'informations d'identification (.mysql.conf) ainsi:

[client]
database=your_database
user=your_username
password=your_password

Raisonnement

La tentative de suppression d'un déclencheur d'une procédure stockée échouera. Je suppose que cela se produit car une variable ne peut contenir qu'une chaîne et drop trigger requiert un nom de déclencheur (pas une chaîne contenant un nom de déclencheur):

create procedure drop_a_trigger()
begin
  declare var1 varchar(1024);
  set var1 = "my_second_trigger";

  drop trigger my_first_trigger;       // OK
  drop trigger address_update_before;  // ERROR 1360 (HY000): Trigger does not exist

end //
delimiter ;

call drop_a_trigger();

Il y a deux fils à ce sujet sur les forums MySQL:

Ils parviennent tous deux à la même conclusion que même l'utilisation d'une procédure stockée n'aidera pas.

7
Ian Mackinnon

Il n'est pas possible de supprimer tous les déclencheurs d'une base de données MySQL à l'aide d'une seule instruction SQL.

Mais avec le code SQL suivant, vous pouvez construire la liste de toutes les instructions 'DROP TRIGGER' ( replace <your_schema> avec votre nom de schéma, par ex. le nom de votre base de données ):

-- set `group_concat_max_len`
SET @@session.group_concat_max_len = @@global.max_allowed_packet;

-- select all the triggers and build the `DROP TRIGGER` SQL
-- replace <your_schema> with your schema name (e.g. your database name)
SELECT GROUP_CONCAT(sql_string SEPARATOR '\n')
FROM (
    SELECT CONCAT('DROP TRIGGER IF EXISTS `', TRIGGER_NAME, '`;') AS sql_string,'1'
    FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = '<your_schema>'
    ) AS sql_strings
GROUP BY '1';

Le résultat de la requête précédente produira quelque chose comme:

DROP TRIGGER IF EXISTS `trigger1`;
DROP TRIGGER IF EXISTS `trigger2`;
(...)

Et vous pouvez utiliser ces instructions SQL pour supprimer définitivement tous les déclencheurs.

La variable système du serveur group_concat_max_len est la longueur de résultat maximale autorisée en octets pour la fonction GROUP_CONCAT (). Comme la valeur par défaut est 1024, nous devons l'augmenter pour éviter un résultat tronqué si nous avons beaucoup de déclencheurs. Je viens d'utiliser la valeur de la variable système du serveur max_allowed_packet , mais convient généralement à tout grand nombre entier. Voir cette autre question .

5
cgaldiolo
SELECT Trigger_Name
FROM `information_schema`.`TRIGGERS`
WHERE TRIGGER_SCHEMA = 'your_schema';

copier les résultats dans le presse-papiers

convertir Trigger_name à DROP TRIGGER <trigger_name>; pour chaque déclencheur en utilisant les balises ^ et S pour le début et la fin de la ligne avec les expressions reg.

exécuter en tant que script sql

3
user3155977

Dans le cas où vous souhaitez les supprimer à l'aide d'une requête sans avoir besoin de sqldump la base de données dans un fichier:

select concat('drop trigger ', trigger_name, ';') from information_schema.triggers where trigger_schema = 'your_schema'; Vous devrez ensuite exporter les résultats (je trouve que c'est le plus simple pour CSV) et lancer les requêtes dans ces résultats.

0
Naguib Ihab

MAC utilisant MAMP:

Il y a quelques petits ajustements à apporter à la réponse acceptée pour nous. Nous devons d'abord cibler mysql dans MAMP. Seconde, sed -r ne fonctionne pas pour Mac, utilisez sed -E au lieu. En supposant la configuration MAMP standard, sans modification des paramètres par défaut de l'utilisateur root , remplacez simplement [nom de la base de données] par votre base de données, puis copiez et collez dans Terminal et appuyez sur entrer.

/Applications/MAMP/Library/bin/mysql -u root -proot --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -E 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | /Applications/MAMP/Library/bin/mysql -u root -proot [db name]

(si vous avez mis à jour votre mot de passe root, remplacez simplement "root" après -p avec votre mot de passe

0
webaholik

Pas sûr de l'existence d'une seule commande à cet effet.

Mais voici comment je l'ai fait il y a quelque temps

  1. Écrire un script pour obtenir la liste des déclencheurs en db.
  2. créer une liste Concated dans le fichier dropTrigger.sql
  3. Exécutez le fichier dropTrigger.SQL

Pour obtenir la liste des déclencheurs, vous pouvez utiliser SHOW trigger ou Tableau des déclencheurs dans le schéma d'information

0