質問

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

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

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

役に立ちましたか?

解決

MySQLの場合、なし: MySQL機能リクエスト

これを許可することは間違いなく非常に悪い考えです。とにかく: IF EXISTS は、(あなたに)未知の構造を持つデータベースで破壊的な操作を実行していることを示します。迅速で汚いローカル作業にはこれが許容される状況がありますが、実稼働データに対して(移行などで)そのようなステートメントを実行したい場合は、火で遊んでいます。

しかし、もしあなたが主張するなら、単純にクライアントの存在を最初にチェックするか、エラーをキャッチすることは難しくありません。

MariaDBは、10.0.2以降では次もサポートしています。

  

ドロップ[列] [存在する場合] col_name

i。 e。

  

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;

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

これは古いスレッドであることは知っていますが、ストアドプロシージャを使用せずにこの要件を処理する簡単な方法があります。これは誰かを助けるかもしれません。

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

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

select * from information_schema.columns where table_schema in (select schema()) and table_name=...

このスレッドは現在かなり古くなっていますが、同じ問題を抱えていました。 これは、MySQL Workbenchを使用した非常に基本的なソリューションでしたが、うまくいきました...

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

テーブルを持っていたテーブルは、今は持っていません ログにエラーが表示されなかったテーブル

その後、「drop a 」を検索/置換して「ADD COLUMN b INT NULL」などに変更し、すべてをもう一度実行できます。...

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top