Si la table existe, déposez la table, créez-la, si elle n'existe pas, créez-la simplement

151

Je suis perplexe, je ne sais pas comment faire ça.

Fondamentalement, 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, créez-la simplement.

Quelqu'un pourrait-il aider?

Merci, George

George
la source
@Shomz, c'est ce qu'ils voulaient. Pourtant, l'existence de cette question et les 20k vues de cette page prouvent que c'est à peu près aussi simple que de convertir l'anglais en grec.
Pacerier
2
@Pacerier Impossible d' accord: διαγραφή πίνακα, εφόσον υπάρχει.
Shomz
@Shomz, il y a une erreur de grammaire.
Pacerier

Réponses:

298

Mettez juste DROP TABLE IF EXISTS `tablename`;avant votre CREATE TABLEdéclaration.

Cette instruction supprime la table si elle existe mais ne lèvera pas d'erreur si ce n'est pas le cas.

G-Nugget
la source
1
Merci! Cela fonctionne également pour une liste de tables ou de vues! DROP TABLE IF EXISTS 'table1', 'table2';et DROP VIEW IF EXISTS 'view1', 'view2';PS- Quelle sorcellerie avez-vous utilisé pour avoir des codes en ligne !?
Campbeln
2
@Campbeln Il suffit de doubler les backticks avant et après le segment de code. Les backticks simples sont ensuite affichés textuellement.
r3mainer
43

Utilisez simplement DROP TABLE IF EXISTS:

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

Essayez d'abord de chercher dans la documentation MySQL si vous rencontrez d'autres problèmes.

r3mainer
la source
8

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

Bien que cela DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );semble raisonnable, cela conduit à une situation où l'ancienne table est déjà partie et qu'une nouvelle n'a pas encore été créée: certains clients peuvent essayer d'accéder à la table des sujets à ce moment.

Le meilleur moyen est de créer une nouvelle table et de la remplacer par 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 en cas d'erreur , car un échec signifie qu'un autre thread n'a pas terminé le même script: soit parce qu'il s'est écrasé au milieu, soit parce qu'il n'a pas encore fini - c'est une bonne idée de inspectez les choses par vous-même.
  • Ensuite, vous devez d'abord vérifier le résultat RENAME ...et ne pas continuer en cas de succès : toute l'opération est terminée avec succès; encore plus, l'exécution suivante RENAME ...peut (et sera) dangereuse si un autre thread a déjà commencé la même séquence (il vaut mieux couvrir ce cas que de ne pas couvrir, voir la note de verrouillage ci-dessous).
  • La seconde RENAME ...remplace atomiquement la définition de table, reportez-vous au manuel MySQL pour plus de détails.
  • Enfin, DROP ...nettoie simplement l'ancienne table, évidemment.

Emballer toutes les instructions avec quelque chose comme SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');permet d'appeler toutes les instructions de manière séquentielle 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 la réplication basée sur des instructions.

Si les données de table doivent survivre à la mise à niveau de la définition de table ... Pour le cas général, il est beaucoup plus complexe de comparer les définitions de table pour découvrir les différences et produire une ALTER ...déclaration appropriée , ce qui n'est pas toujours possible automatiquement, par exemple lorsque les colonnes sont renommées.

Note latérale 1: Vous pouvez traiter les vues en utilisant la même approche, dans ce cas CREATE/DROP TABLEse transforme simplement en tant CREATE/DROP VIEWque RENAME TABLEreste inchangé. En fait, vous pouvez même transformer la table en vue et vice versa.

CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;

Note latérale 2: les utilisateurs de MariaDB devraient être satisfaits CREATE OR REPLACE TABLE/VIEW, qui se soucient déjà du problème du sujet et de ses bons points.

Alex Offshore
la source
1

J'avais besoin de supprimer une table et de la recréer avec des données d'une vue. Je créais un tableau à partir d'une vue et c'est 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 en utilisant MySQL MariaDb.

Sirskoï
la source
drop table nom_table; créer une table comme sélectionnez * dans la vue;
sirskoy
Si vous êtes sur MariaDB (MySQL n'a pas cela), alors vous pouvez simplementCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore