Если таблица существует, удалите таблицу, затем создайте ее, если она не существует, просто создайте ее

151

Я в тупике, я не знаю, как это сделать.

По сути, я просто хочу создать таблицу, но если она существует, ее нужно удалить и заново создать, а не урезать, но если ее не существует, просто создайте ее.

Кто-нибудь сможет помочь?

Спасибо джордж

Джордж
источник
@Shomz, это то, что они хотели. Тем не менее, существование этого вопроса и 20 000 просмотров этой страницы доказывают, что это так же просто, как преобразовать английский в греческий.
Пейсер
2
@Pacerier не могу согласиться: διαγραφή πίνακα, εφόσον υπάρχει.
Шомз
@Shomz, есть грамматическая ошибка.
Pacerier

Ответы:

298

Просто поставьте DROP TABLE IF EXISTS `tablename`;перед своим CREATE TABLEзаявлением.

Эта инструкция удаляет таблицу, если она существует, но не выдает ошибку, если она не существует.

G-самородок
источник
1
Спасибо! Это также работает для списка таблиц или представлений! DROP TABLE IF EXISTS 'table1', 'table2';и DROP VIEW IF EXISTS 'view1', 'view2';PS- Какое колдовство вы использовали, чтобы иметь встроенный код !?
Кэмпбелн
2
@Campbeln Просто удвойте количество кавычек до и после сегмента кода. Одиночные галочки затем показаны дословно.
r3mainer
43

Просто используйте DROP TABLE IF EXISTS:

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

Попробуйте сначала поискать документацию по MySQL, если у вас есть другие проблемы.

r3mainer
источник
8

Ну ... Ха. В течение многих лет никто не упоминал одну тонкую вещь.

Несмотря на то DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );, что это кажется разумным, это приводит к ситуации, когда старая таблица уже исчезла, а новая еще не создана: некоторые клиенты могут попытаться получить доступ к предметной таблице прямо сейчас.

Лучше создать новую таблицу и заменить ее старой (содержимое таблицы теряется):

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`;
  • Вы должны проверить результат CREATE ...и не продолжать в случае ошибки , потому что сбой означает, что другой поток не завершил тот же сценарий: либо потому, что он потерпел крах в середине, либо просто еще не завершил - это хорошая идея осматривать вещи самостоятельно.
  • Затем вы должны сначала проверить результат RENAME ...и не продолжать в случае успеха : вся операция успешно завершена; Более того, выполнение next RENAME ...может (и будет) быть небезопасным, если другой поток уже запустил ту же последовательность (лучше охватить этот случай, чем не закрывать, см. примечание по блокировке ниже).
  • Второй RENAME ...атомарно заменяет определение таблицы, подробности см. В руководстве MySQL .
  • Наконец, DROP ...просто убирает старую таблицу, очевидно.

Обтекание всех операторов чем-то вроде SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');позволяет просто последовательно вызывать все операторы без проверки ошибок, но я не думаю, что это хорошая идея: повышается сложность, а функции блокировки в MySQL не безопасны для репликации на основе операторов.

Если данные таблицы должны выжить при обновлении определения таблицы ... В общем случае гораздо сложнее сравнить сравнения определений таблицы, чтобы найти различия и создать правильное ALTER ...утверждение, что не всегда возможно автоматически, например, при переименовании столбцов.

Примечание 1: Вы можете иметь дело с представлениями, используя тот же подход, в этом случае CREATE/DROP TABLEпросто трансформируется в CREATE/DROP VIEWто время как RENAME TABLEостается неизменным. На самом деле вы можете даже превратить стол в вид и наоборот.

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

Примечание 2: пользователи MariaDB должны быть довольны CREATE OR REPLACE TABLE/VIEW, что уже заботится о предметной проблеме, и это хорошо.

Алекс Оффшор
источник
1

Мне нужно было отбросить таблицу и заново создать данные из представления. Я создавал таблицу из вида, и вот что я сделал:

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

Вышеупомянутое работало для меня, используя MySQL MariaDb.

sirskoy
источник
удалить таблицу table_name; создать таблицу как select * из вида;
Сирской
Если вы находитесь на MariaDB (в MySQL этого нет), вы можете простоCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore