その列が存在する場合、ALTERを使用してMySQLテーブルの列を削除するにはどうすればよいですか?
を使用できることはわかっていますが、存在しないALTER TABLE my_table DROP COLUMN my_column
場合はエラーがスローされます。my_column
列を条件付きで削除するための代替構文はありますか?
MySQLバージョン4.0.18を使用しています。
MySQL の場合、 MySQL Feature Requestはありません。
とにかく、これを許可することは間違いなく本当に悪い考えです: IF EXISTS
(あなたにとって) 未知の構造を持つデータベースで破壊的な操作を実行していることを示します。これが迅速で汚れたローカル作業には受け入れられる状況があるかもしれませんが、(移行などで) 本番データに対してそのようなステートメントを実行したくなる場合は、火遊びをしていることになります。
しかし、あえて言うなら、最初にクライアントで存在を確認することや、エラーをキャッチすることは難しくありません。
MariaDB は、10.0.2 以降、以下もサポートしています。
DROP [COLUMN] [IF EXISTS] col_name
すなわち
ALTER TABLE my_table DROP IF EXISTS my_column;
しかし、MySQL のいくつかのフォークのうちの 1 つだけでサポートされている非標準機能に依存することは、間違いなく悪い考えです。
MySQL では、これに対する言語レベルのサポートはありません。これは、5.0 以降の MySQL information_schema メタデータに関する回避策ですが、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;
より詳細な情報をブログ投稿に書きました。
べき等にするのに役立つ再利用可能なプロシージャを作成しました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
Chase Seibertの答えはうまくいきますが、いくつかのスキーマがある場合は、SELECTを次のように変更したいと付け加えます。
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
このスレッドはかなり古いものだと思いますが、同じ問題がありました。これはMySQL Workbenchを使用した私の非常に基本的なソリューションでしたが、うまくいきました...
x
DROPなどのクエリを記述しますa
。テーブルを持っていたすべてのテーブルには、ログにエラーが表示されていないテーブルはありません
次に、「ドロップ」を見つけて置換a
し、「ADD COLUMN b
INT NULL」などに変更して、すべてを再度実行できます....
少し不格好ですが、最終結果が得られ、プロセス全体を制御/監視できます。SQL スクリプトが再度必要になった場合に備えて保存することを忘れないでください。