Использование ALTER для удаления столбца, если он существует в MySQL
Как можно использовать ALTER для удаления столбца в таблице MySQL, если этот столбец существует?
Я знаю, что могу использовать ALTER my_table DROP COLUMN my_column
, но это вызовет ошибку, если my_column
не существует. Есть ли альтернативный синтаксис для удаления столбца условно?
Я использую MySQL версии 4.0.18.
6 ответов:
для MySQL нет ни одного: MySQL Feature Request.
разрешить это, возможно, действительно плохая идея, в любом случае:
IF EXISTS
указывает, что вы выполняете деструктивные операции над базой данных с (для вас) неизвестной структурой. Могут возникнуть ситуации, когда это приемлемо для быстрой и грязной локальной работы, но если вы испытываете соблазн запустить такое заявление против производственных данных (в миграции и т. д.), ты играешь с огнем.а если вы настаивайте, нетрудно просто проверить наличие первого в клиенте, или поймать ошибку.
MariaDB также поддерживает следующее Начиная с 10.0.2:
DROP [столбец] [если существует] col_name
Я. е.
ALTER TABLE MY_TABLE DROP если существует my_column;
но, возможно, это плохая идея полагаться на нестандартную функцию, поддерживаемую только одной из нескольких вилок MySQL.
в MySQL нет поддержки уровня языка для этого. Вот обходной путь с использованием метаданных MySQL information_schema в 5.0+, но он не будет решать вашу проблему в 4.0.18.
drop procedure if exists schema_change; delimiter ';;' create procedure schema_change() begin /* delete columns if they exist */ if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column1') then alter table table1 drop column `column1`; end if; if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column2') then alter table table1 drop column `column2`; end if; /* add columns */ alter table table1 add column `column1` varchar(255) NULL; alter table table1 add column `column2` varchar(255) NULL; end;; delimiter ';' call schema_change(); drop procedure if exists schema_change;
Я написал более подробную информацию в A блоге.
Я только что построил многоразовую процедуру, которая может помочь сделать
DROP COLUMN
идемпотентна:-- column_exists: DROP FUNCTION IF EXISTS column_exists; DELIMITER $$ CREATE FUNCTION column_exists( tname VARCHAR(64), cname VARCHAR(64) ) RETURNS BOOLEAN BEGIN RETURN 0 < (SELECT COUNT(*) FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = SCHEMA() AND `TABLE_NAME` = tname AND `COLUMN_NAME` = cname); END $$ DELIMITER ; -- drop_column_if_exists: DROP PROCEDURE IF EXISTS drop_column_if_exists; DELIMITER $$ CREATE PROCEDURE drop_column_if_exists( tname VARCHAR(64), cname VARCHAR(64) ) BEGIN IF column_exists(tname, cname) THEN SET @drop_column_if_exists = CONCAT('ALTER TABLE `', tname, '` DROP COLUMN `', cname, '`'); PREPARE drop_query FROM @drop_column_if_exists; EXECUTE drop_query; END IF; END $$ DELIMITER ;
использование:
CALL drop_column_if_exists('my_table', 'my_column');
пример:
SELECT column_exists('my_table', 'my_column'); -- 1 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0
Я знаю, что это старый поток, но есть простой способ справиться с этим требованием без использования хранимых процедур. Это может кому-то помочь.
set @exist_Check := ( select count(*) from information_schema.columns where TABLE_NAME='YOUR_TABLE' and COLUMN_NAME='YOUR_COLUMN' and TABLE_SCHEMA=database() ) ; set @sqlstmt := if(@exist_Check>0,'alter table YOUR_TABLE drop column YOUR_COLUMN', 'select ''''') ; prepare stmt from @sqlstmt ; execute stmt ;
надеюсь, что это поможет кому-то, как это сделал я (после многих проб и ошибок).
ответ Чейза Зайберта работает, но я бы добавил, что если у вас есть несколько схем, вы хотите изменить выбор таким образом:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
Я понимаю, что эта нить довольно старая сейчас, но у меня была та же проблема. Это было мое самое основное решение с использованием MySQL Workbench, но оно отлично работало...
- получить новый редактор sql и выполнить показать таблицы, чтобы получить список ваших таблиц
- выбрать все строки и выберите Копировать в буфер обмена (без кавычек) из контекстного меню
- вставьте список имен в другую вкладку редактора
- напишите свой запрос, т. е. ALTER TABLE
x
падениеa
;- сделать некоторые копирования и вставки, так что вы в конечном итоге с отдельный запрос для каждой таблицы
- переключить ли верстак должен остановиться при возникновении ошибки
- нажмите Выполнить и просмотрите журнал вывода
любые таблицы, которые теперь в таблице не любые таблицы, которые не показали бы ошибку в журналах
тогда вы можете найти / заменить ' drop
a
'изменить его на' добавить столбецb
INT NULL ' и т. д. и запустить все опять эта штука....немного неуклюжий, но, наконец, вы получаете конечный результат, и вы можете контролировать/контролировать весь процесс и не забудьте сохранить вам SQL-скрипты, если они вам понадобятся снова.