Якщо існує таблиця краплі, то створіть її, якщо її немає, просто створіть її


151

Я спотикався, я не знаю, як це робити.

В основному я просто хочу створити таблицю, але якщо вона існує, її потрібно скинути і заново створити, а не усікати, але якщо такої немає, просто створіть її.

Хтось міг би допомогти?

Спасибі, Джордж


@Shomz, ось чого вони хотіли. Однак існування цього питання та 20-ти переглядів цієї сторінки доводить, що це так само просто, як перетворення англійської мови на грецьку.
Pacerier

2
@Pacerier не можу погодитися: διαγραφή πίνακα, εφόσον υπάρχει.
Шомз

@Shomz, є граматична помилка.
Pacerier

Відповіді:


298

Просто поставте DROP TABLE IF EXISTS `tablename`;перед своєю CREATE TABLEзаявою.

Це твердження скидає таблицю, якщо вона існує, але не призведе до помилки, якщо її немає.


1
Дякую! Це також працює для списку таблиць або переглядів! DROP TABLE IF EXISTS 'table1', 'table2';і DROP VIEW IF EXISTS 'view1', 'view2';PS - Яке чаклунство ви використовували, щоб мати `s inline code !?
Кемпбелн

2
@Campbeln Просто подвойте подвійні основи до і після кодового сегмента. Потім окремі бекстейки відображаються дослівно.
r3mainer

43

Просто використовуйте DROP TABLE IF EXISTS:

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

Спробуйте спочатку пошукати документацію MySQL, якщо у вас є інші проблеми.


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 ...і не продовжувати у разі успіху : вся операція успішно завершена; Більше того, наступний запуск 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.


Таблиця для випадання таблиці_ім'я; створити таблицю як select * з перегляду;
sirskoy

Якщо ви перебуваєте на MariaDB (у MySQL цього не вистачає), ви можете простоCREATE OR REPLACE <table_name> AS SELECT * FROM <view>;
Alex Offshore
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.