web-dev-qa-db-fra.com

Si la table existe, supprimez-la, créez-la; si elle n'existe pas, créez-la simplement

Je suis perplexe, je ne sais pas comment s'y prendre.

En gros, je veux juste créer une table, mais si elle existe, elle doit être supprimée et recréée, pas tronquée, mais si elle n'existe pas, il suffit de la créer.

Quelqu'un pourrait-il aider?

Merci, George

114
George

Il suffit de mettre DROP TABLE IF EXISTS `tablename`; avant votre déclaration CREATE TABLE.

Cette instruction supprime la table si elle existe mais ne générera pas d'erreur si ce n'est pas le cas.

237
G-Nugget

Il suffit d'utiliser DROP TABLE IF EXISTS:

DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` ( ... );

Essayez de chercher dans la documentation MySQL first si vous rencontrez des problèmes.

34

Eh bien ... Hein. Pendant des années, personne n'a mentionné une chose subtile.

Bien que DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... ); semble raisonnable, il en résulte une situation dans laquelle l’ancienne table a déjà disparu et que la nouvelle n’a pas encore été créée: un client peut essayer d’accéder à la table sujet à ce moment précis.

Le meilleur moyen est de créer une nouvelle table et de l'échanger avec une ancienne (le contenu de la table est perdu):

CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
  • Vous devriez vérifier le résultat de CREATE ... et ne pas continuer incase d'erreur, car échec signifie qu'un autre thread n'a pas terminé Le même script: soit parce qu'il est tombé en panne, soit tout simplement n’a pas encore fini - c’est une bonne idée d’inspecter les choses par vous-même.
  • Ensuite, vous devriez vérifier le résultat du premier RENAME ... et ne pas Continuer en cas de succès: toute l'opération est réussie Terminée; de plus, exécuter next RENAME ... peut (et sera) toujours dangereux si un autre thread a déjà démarré la même séquence (il est préférable de couvrir ce cas plutôt que de ne pas couvrir, voir la note de verrouillage ci-dessous).
  • Le second RENAME ... remplace atomiquement la définition de la table, reportez-vous à manuel MySQL Pour plus de détails.
  • Enfin, DROP ... nettoie simplement l'ancienne table, Évidemment.

Envelopper toutes les instructions avec quelque chose comme SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade'); permet d'appeler toutes les instructions séquentiellement sans vérification d'erreur, mais je ne pense pas que ce soit une bonne idée: la complexité augmente et les fonctions de verrouillage dans MySQL ne sont pas sûres pour une réplication basée sur des instructions.

Si les données de la table doivent survivre à la mise à niveau de la définition de la table ... Dans les cas généraux, il est beaucoup plus complexe de comparer les définitions de table pour rechercher les différences et produire la bonne instruction ALTER ..., ce qui n'est pas toujours possible automatiquement, par exemple. quand les colonnes sont renommées.

2
Alex Offshore

Je devais supprimer une table et recréer avec les données d'une vue ... Je créais une table à partir d'une vue et voici ce que j'ai fait:

DROP TABLE <table_name>;
CREATE TABLE <table_name> AS SELECT * FROM <view>;

Ce qui précède a fonctionné pour moi avec MySQL MariaDb.

0
sirskoy