Se la tabella esiste, rilascia la tabella quindi crearla, se non esiste basta crearla


151

Sono sconcertato, non so come fare.

Fondamentalmente voglio solo creare una tabella, ma se esiste deve essere eliminata e ricreata, non troncata, ma se non esiste basta crearla.

Qualcuno sarebbe in grado di aiutare?

Grazie George


@Shomz, è quello che volevano. Tuttavia l'esistenza di questa domanda e le 20.000 visualizzazioni di questa pagina dimostrano che è facile quanto convertire l'inglese in greco.
Pacerier,

2
@Pacerier non essere più d'accordo: διαγραφή πίνακα, εφόσον υπάρχει.
Shomz,

@Shomz, c'è un errore grammaticale.
Pacerier,

Risposte:


298

DROP TABLE IF EXISTS `tablename`;Metti solo prima della tua CREATE TABLEdichiarazione.

Tale affermazione elimina la tabella se esiste ma non genererà un errore in caso contrario.


1
Grazie! Questo funziona anche per un elenco di tabelle o viste! DROP TABLE IF EXISTS 'table1', 'table2';e DROP VIEW IF EXISTS 'view1', 'view2';PS: quale stregoneria hai usato per avere `s nel codice inline !?
Campbeln

2
@Campbeln Basta raddoppiare i backtick prima e dopo il segmento di codice. I backtick singoli vengono quindi mostrati alla lettera.
r3mainer


8

Bene ... eh. Per anni nessuno ha menzionato una cosa sottile.

Nonostante DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );sembri ragionevole, porta a una situazione in cui il vecchio tavolo è già sparito e quello nuovo non è ancora stato creato: alcuni client potrebbero provare ad accedere al tavolo degli argomenti proprio in questo momento.

Il modo migliore è creare una nuova tabella e scambiarla con una vecchia (i contenuti della tabella vanno persi):

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`;
  • Dovresti controllare il risultato CREATE ...e non continuare in caso di errore , perché fallimento significa che l'altro thread non ha terminato lo stesso script: o perché si è bloccato nel mezzo o semplicemente non è ancora terminato - è una buona idea ispeziona le cose da solo.
  • Quindi, dovresti controllare prima il risultato RENAME ...e non continuare in caso di successo : l'intera operazione è stata completata con successo; ancora di più, l'esecuzione successiva RENAME ...può (e sarà) non sicura se un altro thread ha già avviato la stessa sequenza (è meglio coprire questo caso che non coprire, vedere la nota di blocco di seguito).
  • Second RENAME ...sostituisce atomicamente la definizione della tabella, fare riferimento al manuale di MySQL per i dettagli.
  • Alla fine, DROP ...pulisce il vecchio tavolo, ovviamente.

Il wrapping di tutte le istruzioni con qualcosa del genere SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');consente di richiamare tutte le istruzioni in sequenza senza controllo degli errori, ma non credo sia una buona idea: aumenti di complessità e funzioni di blocco in MySQL non sono sicure per la replica basata su istruzioni.

Se i dati della tabella dovessero sopravvivere all'aggiornamento della definizione della tabella ... Per il caso generale è molto più complessa la storia del confronto delle definizioni della tabella per scoprire le differenze e produrre ALTER ...un'istruzione corretta , il che non è sempre possibile automaticamente, ad esempio quando le colonne vengono rinominate.

Nota a margine 1: è possibile gestire le viste utilizzando lo stesso approccio, in questo caso CREATE/DROP TABLEsi trasforma semplicemente in CREATE/DROP VIEWmentre RENAME TABLErimane invariato. In effetti puoi persino trasformare la tabella in vista e viceversa.

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`;

Nota a margine 2: gli utenti di MariaDB dovrebbero essere contenti CREATE OR REPLACE TABLE/VIEW, che si preoccupa già del problema dell'argomento e va bene i punti.


1

Avevo bisogno di eliminare una tabella e ricrearla con un dato da una vista. Stavo creando una tabella da una vista e questo è quello che ho fatto:

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

Quanto sopra ha funzionato per me usando MySQL MariaDb.


drop table table_name; crea una tabella come seleziona * dalla vista;
Sirskoy,

Se sei su MariaDB (MySQL manca di questo), allora puoi semplicementeCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.