Использование ALTER для удаления столбца, если он существует в MySQL
Вопрос
Как можно использовать ALTER для удаления столбца в таблице MySQL, если этот столбец существует?
Я знаю, что могу использовать ALTER TABLE my_table DROP COLUMN my_column
, но это выдаст ошибку , если my_column
не существует.Существует ли альтернативный синтаксис для условного удаления столбца?
Я использую MySQL версии 4.0.18.
Решение
Для MySQL такого не существует: Запрос функции MySQL.
В любом случае, допускать это, возможно, действительно плохая идея: IF EXISTS
указывает, что вы выполняете деструктивные операции над базой данных с (для вас) неизвестной структурой.Могут быть ситуации, когда это приемлемо для быстрой и грязной локальной работы, но если у вас возникнет соблазн выполнить такое утверждение для производственных данных (при миграции и т.д.), вы играете с огнем.
Но если вы настаиваете, нетрудно просто сначала проверить наличие в клиенте или перехватить ошибку.
MariaDB также поддерживает следующее, начиная с версии 10.0.2:
УДАЛИТЕ [СТОЛБЕЦ] [ЕСЛИ СУЩЕСТВУЕТ] имя_колонки
i.e.
ИЗМЕНИТЬ ТАБЛИЦУ my_table, УДАЛИТЬ, ЕСЛИ СУЩЕСТВУЕТ 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;
Я написал более подробную информацию в сообщении в блоге. . р>
Я знаю, что это старый поток, но есть простой способ выполнить это требование без использования хранимых процедур. Это может кому-то помочь.
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 ;
Надеюсь, это поможет кому-то, как и мне (после долгих проб и ошибок).
Я только что создал многоразовую процедуру, которая может помочь сделать DROP COLUMN
идемпотентный:
-- column_exists:
DROP FUNCTION IF EXISTS column_exists;
DELIMITER $$
CREATE FUNCTION column_exists(
tname VARCHAR(64),
cname VARCHAR(64)
)
RETURNS BOOLEAN
READS SQL DATA
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
Ответ Чейза Сейберта работает, но я бы добавил, что если у вас есть несколько схем, вы хотите изменить SELECT следующим образом:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
Я понимаю, что эта тема довольно старая, но у меня была та же проблема. Это было мое очень простое решение с использованием MySQL Workbench, но оно работало нормально ...
<Ол> x
DROP a
; любые таблицы, в которых была таблица, не имеют любые таблицы, в которых не было ошибок в журналах
тогда вы можете найти / заменить 'drop a
", измените его на" ADD COLUMN b
INT NULL "и т. д. и снова запустите все это .... р>
немного неуклюже, но в конце концов вы получите конечный результат, и вы можете контролировать / контролировать весь процесс и не забывать сохранять свои сценарии sql на случай, если они вам понадобятся снова.