web-dev-qa-db-ja.com

ALTER TABLEの前に列が存在するかどうかを確認します-mysql

ALTER TABLE ADD coumn_nameステートメントの実行前(または実行時)にmySQL DBに列が存在するかどうかを確認する方法はありますか? IF column DOES NOT EXIST ALTER TABLEの並べ替え。

ALTER IGNORE TABLE my_table ADD my_columnを試しましたが、追加しようとしている列が既に存在する場合、エラーが引き続き発生します。

編集:ユースケースは、既にインストールされているWebアプリのテーブルをアップグレードすることです。したがって、物事を単純にするために、必要な列が存在することを確認し、存在しない場合はALTER TABLEを使用して追加します

20
julio

Mysql制御ステートメント(例:「IF」)はストアドプロシージャでのみ機能するため、一時的なものを作成して実行できます。

DROP PROCEDURE IF EXISTS add_version_to_actor;

DELIMITER $$

CREATE DEFINER=CURRENT_USER PROCEDURE add_version_to_actor ( ) 
BEGIN
DECLARE colName TEXT;
SELECT column_name INTO colName
FROM information_schema.columns 
WHERE table_schema = 'connjur'
    AND table_name = 'actor'
AND column_name = 'version';

IF colName is null THEN 
    ALTER TABLE  actor ADD  version TINYINT NOT NULL DEFAULT  '1' COMMENT  'code version of actor when stored';
END IF; 
END$$

DELIMITER ;

CALL add_version_to_actor;

DROP PROCEDURE add_version_to_actor;
9
gerardw

これを試すことができると思いますか?:

SELECT IFNULL(column_name, '') INTO @colName
FROM information_schema.columns 
WHERE table_name = 'my_table'
AND column_name = 'my_column';

IF @colName = '' THEN 
    -- ALTER COMMAND GOES HERE --
END IF;

それはワンライナーではありませんが、少なくともそれがあなたのために働くかどうか見ることができますか?少なくとも、より良い解決策を待っている間。

8
Nonym

ユーティリティ関数と手順

まず、外部キー、通常のキー、および列をドロップするようなことを行うために使用するユーティリティ関数とプロシージャのセットがあります。必要に応じて使用できるように、データベースに残しておきます。

どうぞ。

delimiter $$

create function column_exists(ptable text, pcolumn text)
  returns bool
  reads sql data
begin
  declare result bool;
  select
    count(*)
  into
    result
  from
    information_schema.columns
  where
    `table_schema` = 'my_database' and
    `table_name` = ptable and
    `column_name` = pcolumn;
  return result;
end $$

create function constraint_exists(ptable text, pconstraint text)
  returns bool
  reads sql data
begin
  declare result bool;
  select
    count(*)
  into
    result
  from
    information_schema.table_constraints
  where
    `constraint_schema` = 'my_database' and
    `table_schema` = 'my_database' and
    `table_name` = ptable and
    `constraint_name` = pconstraint;
  return result;
end $$

create procedure drop_fk_if_exists(ptable text, pconstraint text)
begin
  if constraint_exists(ptable, pconstraint) then
    set @stat = concat('alter table ', ptable, ' drop foreign key ', pconstraint);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

create procedure drop_key_if_exists(ptable text, pconstraint text)
begin
  if constraint_exists(ptable, pconstraint) then
    set @stat = concat('alter table ', ptable, ' drop key ', pconstraint);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

create procedure drop_column_if_exists(ptable text, pcolumn text)
begin
  if column_exists(ptable, pcolumn) then
    set @stat = concat('alter table ', ptable, ' drop column ', pcolumn);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

delimiter ;

上記のユーティリティを使用して制約と列を削除する

それらが適切に配置されていれば、それらを使用して列と制約の存在を確認するのは非常に簡単です。

-- Drop service.component_id
call drop_fk_if_exists('service', 'fk_service_1');
call drop_key_if_exists('service', 'component_id');
call drop_column_if_exists('service', 'component_id');

-- Drop commit.component_id
call drop_fk_if_exists('commit', 'commit_ibfk_1');
call drop_key_if_exists('commit', 'commit_idx1');
call drop_column_if_exists('commit', 'component_id');

-- Drop component.application_id
call drop_fk_if_exists('component', 'fk_component_1');
call drop_key_if_exists('component', 'application_id');
call drop_column_if_exists('component', 'application_id');
6
Willie Wheeler

ジョンワトソンによる以下の例で、count文を作成します。

 SELECT count(*) FROM information_schema.COLUMNS
     WHERE COLUMN_NAME = '...'
     and TABLE_NAME = '...'
     and TABLE_SCHEMA = '...'

その結果を整数で保存し、ADD COLUMN文を適用するための条件にします。

4
Duvan Barros

かなり古い投稿ですが、それでもこの問題に対する解決策を共有するのは良い気分です。列が存在しない場合、例外が確実に発生し、テーブルに列を作成しています。

以下のコードを使用しました。

 try
   {
         DATABASE_QUERY="SELECT gender from USER;";
         db.rawQuery(DATABASE_QUERY, null);
   }
   catch (Exception e)
   {
    e.printStackTrace();

        DATABASE_UPGRADE="alter table USER ADD COLUMN gender VARCHAR(10) DEFAULT 0;";
                db.execSQL(DATABASE_UPGRADE);
   } 
1
Wahib Ul Haq
DELIMITER $$

DROP PROCEDURE IF EXISTS `addcol` $$
CREATE DEFINER=`admin`@`localhost` PROCEDURE `addcol`(tbn varchar(45), cn varchar(45), ct varchar(45))
BEGIN
#tbn: table name, cn: column name, ct: column type
DECLARE CONTINUE HANDLER FOR 1060 BEGIN END;
set cn = REPLACE(cn, ' ','_');
set @a = '';
set @a = CONCAT("ALTER TABLE `", tbn ,"` ADD column `", cn ,"` ", ct);
PREPARE stmt FROM @a;
EXECUTE stmt;

END $$

DELIMITER ;
0
Richards RIc

この構文は私のために働く:

<テーブル名>のように列を表示する '<列名>'

この投稿の詳細: https://mzulkamal.com/blog/mysql-5-7-check-if-column-exist?viewmode=

0
shamcs

列が存在する場合、CONTINUEハンドラーを使用してプロシージャを作成できます(このコードはPHPMyAdminでは機能しないことに注意してください)。

DROP PROCEDURE IF EXISTS foo;
CREATE PROCEDURE foo() BEGIN
    DECLARE CONTINUE HANDLER FOR 1060 BEGIN END;
    ALTER TABLE `tableName` ADD `columnName` int(10) NULL AFTER `otherColumn`;
END;
CALL foo();
DROP PROCEDURE foo;

列が既に存在する場合、このコードはエラーを発生させません。それは何もせず、残りのSQLの実行を続けます。

0
OMA