проверить, существует ли столбец до ALTER TABLE - mysql - PullRequest
20 голосов
/ 22 ноября 2011

Есть ли способ проверить, существует ли столбец в БД mySQL до (или как) выполнения оператора ALTER TABLE ADD coumn_name? Вроде IF column DOES NOT EXIST ALTER TABLE вещь.

Я пытался ALTER IGNORE TABLE my_table ADD my_column, но все равно выдает ошибку, если столбец, который я добавляю, уже существует.

РЕДАКТИРОВАТЬ: вариант использования - обновить таблицу в уже установленном веб-приложении - поэтому, чтобы упростить задачу, я хочу убедиться, что нужные мне столбцы существуют, а если нет, добавьте их с помощью ALTER TABLE

Ответы [ 9 ]

9 голосов
/ 31 июля 2012

Поскольку операторы управления 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;
8 голосов
/ 22 ноября 2011

Как вы думаете, вы можете попробовать это?:

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;

Это не однострочник, но можете ли вы хотя бы посмотреть, сработает ли он для вас? По крайней мере, в ожидании лучшего решения ..

6 голосов
/ 14 марта 2014

Сервисные функции и процедуры

Во-первых, у меня есть набор служебных функций и процедур, которые я использую для таких вещей, как удаление внешних ключей, обычных ключей и столбцов. Я просто оставляю их в базе данных, чтобы использовать их по мере необходимости.

Вот они.

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');
4 голосов
/ 19 сентября 2013

Составьте счетное предложение с примером ниже Джона Уотсона.

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

Сохраните этот результат в целое число, а затем поставьте условие применить предложение ADD COLUMN.

1 голос
/ 30 октября 2012

Хотя это довольно старый пост, но все же я рад поделиться своим решением этой проблемы. Если столбец не существует, то исключение будет происходить определенно, а затем я создаю столбец в таблице.

Я только что использовал код ниже:

 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);
   } 
0 голосов
/ 03 ноября 2014

Согласно сообществу MYSQL:

IGNORE - это расширение MySQL для стандартного SQL.Он управляет работой ALTER TABLE, если в новой таблице присутствуют дубликаты уникальных ключей или появляются предупреждения при включенном строгом режиме.Если IGNORE не указан, копия прерывается и откатывается при возникновении ошибок дубликата ключа.Если указан IGNORE, используется только одна строка из строк с дубликатами на уникальном ключе.Другие конфликтующие строки удаляются.Неверные значения усекаются до ближайшего подходящего допустимого значения.

Таким образом, рабочий код: ALTER IGNORE TABLE CLIENTS ADD CLIENT_NOTES TEXT DEFAULT NULL;

Данные размещены здесь: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

0 голосов
/ 24 июня 2014
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 голосов
/ 14 февраля 2014

Вы можете создать процедуру с обработчиком 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 голосов
/ 22 ноября 2011

Вы можете проверить, существует ли столбец с:

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

...

Просто введите имя столбца, имя таблицы и имя базы данных.

...