Existe-t-il un moyen de vérifier si une colonne existe dans une base de données mySQL avant (ou sous) l'exécution de l'instruction ALTER TABLE ADD coumn_name
? Tri d'une chose IF column DOES NOT EXIST ALTER TABLE
.
J'ai essayé ALTER IGNORE TABLE my_table ADD my_column
mais cela jette toujours l'erreur si la colonne que j'ajoute existe déjà.
EDIT: le cas d’utilisation consiste à mettre à jour une table dans une application Web déjà installée - alors, pour rester simple, je veux être sûr que les colonnes dont j’ai besoin existent, et si ce n’est pas le cas, ajoutez-les en utilisant ALTER TABLE
Etant donné que les instructions de contrôle mysql (par exemple, "IF") ne fonctionnent que dans les procédures stockées, une instruction temporaire peut être créée et exécutée:
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;
Pensez-vous pouvoir essayer ceci ?:
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;
Ce n'est pas une ligne, mais pouvez-vous au moins voir si cela fonctionnera pour vous? Au moins en attendant une meilleure solution ..
Tout d'abord, j'ai un ensemble de fonctions utilitaires et de procédures que j'utilise pour effectuer des opérations telles que la suppression de clés étrangères, de clés normales et de colonnes. Je les laisse simplement dans la base de données pour pouvoir les utiliser au besoin.
Les voici.
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 ;
Avec ceux en place, il est assez facile de les utiliser pour vérifier l'existence des colonnes et des contraintes:
-- 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');
Faites une phrase de comptage avec l'exemple ci-dessous de John Watson.
SELECT count(*) FROM information_schema.COLUMNS
WHERE COLUMN_NAME = '...'
and TABLE_NAME = '...'
and TABLE_SCHEMA = '...'
Enregistrez ce résultat dans un entier, puis indiquez comme condition d'appliquer la phrase ADD COLUMN
.
Bien que ce soit un vieux post, mais je suis toujours heureux de partager ma solution à ce problème. Si la colonne n'existe pas, une exception se produirait définitivement et je crée alors la colonne dans la table.
Je viens d'utiliser le code ci-dessous:
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 ;
Vous pouvez créer une procédure avec un gestionnaire CONTINUE au cas où la colonne existe (veuillez noter que ce code ne fonctionne pas dans 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;
Ce code ne doit générer aucune erreur si la colonne existe déjà. Il ne fera que rien et continuera à exécuter le reste du code SQL.