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
を使用して追加します
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;
これを試すことができると思いますか?:
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;
それはワンライナーではありませんが、少なくともそれがあなたのために働くかどうか見ることができますか?少なくとも、より良い解決策を待っている間。
まず、外部キー、通常のキー、および列をドロップするようなことを行うために使用するユーティリティ関数とプロシージャのセットがあります。必要に応じて使用できるように、データベースに残しておきます。
どうぞ。
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');
ジョンワトソンによる以下の例で、count文を作成します。
SELECT count(*) FROM information_schema.COLUMNS
WHERE COLUMN_NAME = '...'
and TABLE_NAME = '...'
and TABLE_SCHEMA = '...'
その結果を整数で保存し、ADD COLUMN
文を適用するための条件にします。
かなり古い投稿ですが、それでもこの問題に対する解決策を共有するのは良い気分です。列が存在しない場合、例外が確実に発生し、テーブルに列を作成しています。
以下のコードを使用しました。
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);
}
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 ;
この構文は私のために働く:
<テーブル名>のように列を表示する '<列名>'
この投稿の詳細: https://mzulkamal.com/blog/mysql-5-7-check-if-column-exist?viewmode=
列が存在する場合、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の実行を続けます。