108

その列が存在する場合、ALTERを使用してMySQLテーブルの列を削除するにはどうすればよいですか?

を使用できることはわかっていますが、存在しないALTER TABLE my_table DROP COLUMN my_column場合はエラーがスローされます。my_column列を条件付きで削除するための代替構文はありますか?

MySQLバージョン4.0.18を使用しています。

4

8 に答える 8

84

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 つだけでサポートされている非標準機能に依存することは、間違いなく悪い考えです。

于 2008-10-06T10:31:22.140 に答える
45

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;

より詳細な情報をブログ投稿に書きました。

于 2010-01-22T20:57:03.920 に答える
18

べき等にするのに役立つ再利用可能なプロシージャを作成しました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
于 2018-04-05T15:37:55.830 に答える
5

Chase Seibertの答えはうまくいきますが、いくつかのスキーマがある場合は、SELECTを次のように変更したいと付け加えます。

select * from information_schema.columns where table_schema in (select schema()) and table_name=...
于 2010-01-28T16:03:50.480 に答える
-3

このスレッドはかなり古いものだと思いますが、同じ問題がありました。これはMySQL Workbenchを使用した私の非常に基本的なソリューションでしたが、うまくいきました...

  1. 新しいSQLエディタを入手し、SHOW TABLESを実行してテーブルのリストを取得してください
  2. すべての行を選択し、コンテキスト メニューから [クリップボードにコピー (引用なし)] を選択します。
  3. 名前のリストを別のエディター タブに貼り付けます
  4. ALTER TABLE xDROPなどのクエリを記述しますa
  5. コピーと貼り付けを行うと、テーブルごとに個別のクエリが作成されます
  6. エラーが発生したときにワークベンチを停止するかどうかを切り替えます
  7. 実行を押して、出力ログを調べます

テーブルを持っていたすべてのテーブルには、ログにエラーが表示されていないテーブルはありません

次に、「ドロップ」を見つけて置換aし、「ADD COLUMN bINT NULL」などに変更して、すべてを再度実行できます....

少し不格好ですが、最終結果が得られ、プロセス全体を制御/監視できます。SQL スクリプトが再度必要になった場合に備えて保存することを忘れないでください。

于 2011-06-23T12:01:44.653 に答える