Jeśli istnieje tabela drop table, utwórz ją, jeśli nie istnieje, po prostu ją utwórz

151

Jestem zakłopotany, nie wiem, jak się do tego zabrać.

Zasadniczo chcę tylko utworzyć tabelę, ale jeśli istnieje, należy ją usunąć i ponownie utworzyć, a nie skrócić, ale jeśli nie istnieje, po prostu ją utwórz.

Czy ktoś byłby w stanie pomóc?

Dzięki, George

Jerzy
źródło
@Shomz, tego właśnie chcieli. Jednak istnienie tego pytania i 20 tysięcy wyświetleń tej strony dowodzi, że jest to tak proste, jak konwersja języka angielskiego na grecki.
Pacerier
2
@Pacerier nie zgodzić: διαγραφή πίνακα, εφόσον υπάρχει.
Shomz
@Shomz, wystąpił błąd gramatyczny.
Pacerier

Odpowiedzi:

298

Po prostu umieść DROP TABLE IF EXISTS `tablename`;przed CREATE TABLEoświadczeniem.

Ta instrukcja usuwa tabelę, jeśli istnieje, ale nie zgłosi błędu, jeśli tak nie jest.

G-Nugget
źródło
1
Dzięki! Działa to również w przypadku listy tabel lub widoków! DROP TABLE IF EXISTS 'table1', 'table2';i DROP VIEW IF EXISTS 'view1', 'view2';PS: Jakie czary użyłeś, aby mieć wbudowany kod !?
Campbeln
2
@Campbeln Wystarczy podwoić cyfry przed i po segmencie kodu. Następnie wyświetlane są pojedyncze znaki odwrotne.
r3mainer
43

Po prostu użyj DROP TABLE IF EXISTS:

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

Spróbuj najpierw przeszukać dokumentację MySQL, jeśli masz inne problemy.

r3mainer
źródło
8

Cóż ... Huh. Od lat nikt nie wspomniał o jednej subtelnej rzeczy.

Mimo, DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );że wydaje się to rozsądne, prowadzi to do sytuacji, w której stary stół już nie istnieje, a nowy nie został jeszcze utworzony: jakiś klient może w tym momencie próbować uzyskać dostęp do tabeli tematów.

Lepszym sposobem jest utworzenie zupełnie nowej tabeli i zamiana jej na starą (zawartość tabeli jest tracona):

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`;
  • Powinieneś sprawdzić wynik CREATE ...i nie kontynuować w przypadku błędu , ponieważ awaria oznacza, że ​​inny wątek nie zakończył tego samego skryptu: albo zawiesił się w środku, albo po prostu jeszcze się nie skończył - dobrze sprawdź rzeczy samodzielnie.
  • Następnie należy najpierw sprawdzić wynik RENAME ...i nie kontynuować w przypadku sukcesu : cała operacja została zakończona pomyślnie; Co więcej, uruchomienie następnego RENAME ...może (i będzie) niebezpieczne, jeśli inny wątek już rozpoczął tę samą sekwencję (lepiej omówić ten przypadek niż nie, patrz uwaga na temat blokowania poniżej).
  • Druga RENAME ...niepodzielnie zastępuje definicję tabeli, szczegółowe informacje można znaleźć w podręczniku MySQL .
  • W końcu DROP ...oczywiście po prostu sprząta stary stół.

Zawijanie wszystkich instrukcji czymś takim jak SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');pozwala po prostu wywoływać wszystkie instrukcje sekwencyjnie bez sprawdzania błędów, ale nie sądzę, aby to był dobry pomysł: zwiększa się złożoność i funkcje blokujące w MySQL nie są bezpieczne dla replikacji opartej na instrukcjach.

Jeśli dane tabeli powinny przetrwać aktualizację definicji tabeli ... W ogólnym przypadku jest to znacznie bardziej złożona historia o porównywaniu definicji tabel w celu znalezienia różnic i stworzenia odpowiedniego ALTER ...zestawienia, co nie zawsze jest możliwe automatycznie, np. Przy zmianie nazw kolumn.

Uwaga dodatkowa 1: Możesz radzić sobie z widokami, używając tego samego podejścia, w tym przypadku CREATE/DROP TABLEpo prostu przekształca się w CREATE/DROP VIEWpodczas gdy RENAME TABLEpozostaje niezmieniony. W rzeczywistości możesz nawet zmienić tabelę w widok i odwrotnie.

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

Uwaga dodatkowa 2: użytkownicy MariaDB powinni być zadowoleni CREATE OR REPLACE TABLE/VIEW, która już dba o problem tematyczny i to jest dobre punkty.

Alex Offshore
źródło
1

Musiałem usunąć tabelę i utworzyć ją ponownie z danymi z widoku. Tworzyłem tabelę z widoku i tak zrobiłem:

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

Powyższe działało dla mnie przy użyciu MySQL MariaDb.

sirskoy
źródło
drop table nazwa_tabeli; utwórz tabelę jako wybierz * z widoku;
sirskoy
Jeśli korzystasz z MariaDB (MySQL tego nie ma), możesz po prostuCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore