WedX - журнал о программировании и компьютерных науках

проверить, существует ли столбец перед ALTER TABLE mysql

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

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

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

21.11.2011

  • Пробовали ли вы проверить описание синтаксиса изменения табличное заявление? Этот материал задокументирован, понимаете? 22.11.2011
  • Не беспокоит ли вас то, что вы выполняете изменения DDL в своих таблицах, не зная их структуры? Каков вариант использования? 22.11.2011
  • @GolezTrol -- да, ясно, что я читал документы, но я получаю сообщение об ошибке даже при использовании IGNORE, как описано на странице, на которую вы ссылаетесь, -- поэтому я спрашиваю, как создать таблицу изменений только тогда, когда столбец не не существует. Это неясно? 22.11.2011
  • @Russell Один из вариантов использования - сценарии отката. Если прямой сценарий по какой-либо причине дает сбой, сценарий отката может попытаться откатить изменения, которые никогда не выполнялись изначально. Таким образом, проверка позволяет сценарию отката решить для любого заданного возврата, делать ли это. 26.02.2014
  • @julio, никогда не поздно отметить ответ принятым и передать долгожданную часть ТАКОЙ кармы тому, кто пытался тебе помочь. 28.09.2016

Ответы:


1

Поскольку операторы управления 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;
31.07.2012

2

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

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;

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

21.11.2011
  • Я получаю ошибку Unknown column 'column_name' in 'field list', если столбец не существует... 27.08.2014
  • У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с 'IF @colName = '' THEN ALTER TABLE овощи ДОБАВЬТЕ овощной_цвет VARCHAR(25' в строке 1 08.05.2018

  • 3

    Вспомогательные функции и процедуры

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

    Они здесь.

    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');
    
    14.03.2014

    4

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

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

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

    19.09.2013
  • Не могли бы вы уточнить, как сохранить результат и сделать его условием для применения ДОБАВИТЬ КОЛОНКУ? 19.09.2013

  • 5

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

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

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

    22.11.2011
  • это дает мне #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS ( SELECT * FROM information_schema.COLUMNS WHERE COLUMN_NAME' 22.11.2011
  • IF можно использовать только внутри процедуры, триггера и т. д. 23.10.2014

  • 6

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

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

     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);
       } 
    
    30.10.2012
  • В случае большого количества записей о поле в USER может быть полезно ограничить поиск одним элементом, чтобы он был быстрее, то есть ВЫБЕРИТЕ пол из ограничения пользователя 1; 14.05.2019

  • 7

    Вы можете создать процедуру с обработчиком 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.

    14.02.2014

    8

    Этот синтаксис работает для меня:

    ПОКАЗАТЬ КОЛОННЫ ИЗ ‹ имя_таблицы > НРАВИТСЯ '‹ имя_столбца >'

    Подробнее в этом посте: https://mzulkamal.com/blog/mysql-5-7-check-if-column-exist?viewmode=0

    02.08.2019

    9

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

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

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

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

    03.11.2014
  • Извините, чувак, но ИГНОР этого не делает. Он проверяет только наличие дубликатов в уникальных ключах, не более того. 10.03.2015
  • Привет, bksi, я надеюсь, что вы проверили сообщество разработчиков MySQL в отношении этого поста, прежде чем добавлять свое предложение к нему, поскольку я дал ссылку на него. И если вы правы, а сообщество MySQL ошибается, также предложите им перепроверить их форум и получить от вас помощь. 16.03.2015
  • Вы тестировали свое решение? Потому что я проверил это, и это не работает. Когда у вас есть столбец и вы пытаетесь изменить его, чтобы добавить тот же столбец с игнорированием, произойдет та же ошибка. 17.03.2015
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

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

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]