その列が存在する場合、ALTERを使用してMySQLテーブルの列を削除するにはどうすればよいですか?
使用できることはわかっていますがALTER TABLE my_table DROP COLUMN my_column
、my_column
存在しない場合はエラーがスローされます。条件付きで列を削除するための代替構文はありますか?
MySQLバージョン4.0.18を使用しています。
その列が存在する場合、ALTERを使用してMySQLテーブルの列を削除するにはどうすればよいですか?
使用できることはわかっていますがALTER TABLE my_table DROP COLUMN my_column
、my_column
存在しない場合はエラーがスローされます。条件付きで列を削除するための代替構文はありますか?
MySQLバージョン4.0.18を使用しています。
回答:
:MySQLの場合、何もありません MySQLの機能のリクエストが。
とにかく、これを許可することは間違いなく本当に悪い考えです:(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以降のMySQLinformation_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;
私はブログ投稿にいくつかのより詳細な情報を書きました。
これが古いスレッドであることは知っていますが、ストアドプロシージャを使用せずにこの要件を処理する簡単な方法があります。これは誰かを助けるかもしれません。
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
おそらく、これを解決する最も簡単な方法(それは機能します)は次のとおりです。
CREATE new_table AS SELECT id、col1、col2、...(最終テーブルに実際に必要な列のみ)FROM my_table;
my_tableの名前をold_tableに、new_tableの名前をmy_tableに変更します。
DROP old_table;
または、必要に応じてロールバックのためにold_tableを保持します。
これは機能しますが、外部キーは移動されません。後でそれらをmy_tableに再度追加する必要があります。また、my_tableを参照する他のテーブルの外部キーを修正する必要があります(新しいmy_tableを指す)。
幸運を...
IF EXISTS (SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName'
AND TABLE_SCHEMA = SchemaName)
BEGIN
ALTER TABLE TableName DROP COLUMN ColumnName;
END;
このスレッドはかなり古いことに気づきましたが、同じ問題を抱えていました。これはMySQLWorkbenchを使用した非常に基本的なソリューションでしたが、正常に機能しました...
x
DROP a
;テーブルがあったテーブルには、ログにエラーが表示されなかったテーブルがありません。
次に、「drop a
」を検索/置換し、「ADD COLUMN b
INT NULL」などに変更して、すべてを再度実行します。
少し不格好ですが、最終的には最終結果が得られ、プロセス全体を制御/監視し、SQLスクリプトが再び必要になった場合に備えて保存することを忘れないでください。