Pregunta

¿Cómo se puede usar ALTER para colocar una columna en una tabla MySQL si esa columna existe?

Sé que puedo usar ALTER TABLE my_table DROP COLUMN my_column , pero eso arrojará un error si my_column no existe. ¿Existe una sintaxis alternativa para descartar la columna condicionalmente?

Estoy usando MySQL versión 4.0.18.

¿Fue útil?

Solución

Para MySQL, no hay ninguno: Solicitud de funciones de MySQL .

Permitir que esto sea una mala idea, de todos modos: IF EXISTS indica que está ejecutando operaciones destructivas en una base de datos con (para usted) estructura desconocida. Puede haber situaciones en las que esto sea aceptable para el trabajo local rápido y sucio, pero si está tentado a ejecutar dicha declaración contra los datos de producción (en una migración, etc.), está jugando con fuego.

Pero si insiste, no es difícil simplemente verificar la existencia primero en el cliente, o detectar el error.

MariaDB también admite lo siguiente a partir de 10.0.2:

  

DROP [COLUMN] [IF EXISTS] col_name

i. e.

  

ALTER TABLE my_table DROP IF EXISTS my_column;

Pero podría decirse que es una mala idea confiar en una característica no estándar compatible con solo uno de varios tenedores de MySQL.

Otros consejos

No hay soporte de nivel de lenguaje para esto en MySQL. Aquí hay una solución alternativa que involucra metadatos de MySQL information_schema en 5.0+, pero no resolverá su problema en 4.0.18.

drop procedure if exists schema_change;

delimiter ';;'
create procedure schema_change() begin

    /* delete columns if they exist */
    if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column1') then
        alter table table1 drop column `column1`;
    end if;
    if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column2') then
        alter table table1 drop column `column2`;
    end if;

    /* add columns */
    alter table table1 add column `column1` varchar(255) NULL;
    alter table table1 add column `column2` varchar(255) NULL;

end;;

delimiter ';'
call schema_change();

drop procedure if exists schema_change;

Escribí información más detallada en una publicación de blog .

Sé que este es un hilo antiguo, pero hay una manera simple de manejar este requisito sin usar procedimientos almacenados. Esto puede ayudar a alguien.

set @exist_Check := (
    select count(*) from information_schema.columns 
    where TABLE_NAME='YOUR_TABLE' 
    and COLUMN_NAME='YOUR_COLUMN' 
    and TABLE_SCHEMA=database()
) ;
set @sqlstmt := if(@exist_Check>0,'alter table YOUR_TABLE drop column YOUR_COLUMN', 'select ''''') ;
prepare stmt from @sqlstmt ;
execute stmt ;

Espero que esto ayude a alguien, como lo hizo yo (después de muchas pruebas y errores).

Acabo de construir un procedimiento reutilizable que puede ayudar a hacer que DROP COLUMN sea idempotente:

-- column_exists:

DROP FUNCTION IF EXISTS column_exists;

DELIMITER $
CREATE FUNCTION column_exists(
  tname VARCHAR(64),
  cname VARCHAR(64)
)
  RETURNS BOOLEAN
  READS SQL DATA
  BEGIN
    RETURN 0 < (SELECT COUNT(*)
                FROM `INFORMATION_SCHEMA`.`COLUMNS`
                WHERE `TABLE_SCHEMA` = SCHEMA()
                      AND `TABLE_NAME` = tname
                      AND `COLUMN_NAME` = cname);
  END $
DELIMITER ;

-- drop_column_if_exists:

DROP PROCEDURE IF EXISTS drop_column_if_exists;

DELIMITER $
CREATE PROCEDURE drop_column_if_exists(
  tname VARCHAR(64),
  cname VARCHAR(64)
)
  BEGIN
    IF column_exists(tname, cname)
    THEN
      SET @drop_column_if_exists = CONCAT('ALTER TABLE `', tname, '` DROP COLUMN `', cname, '`');
      PREPARE drop_query FROM @drop_column_if_exists;
      EXECUTE drop_query;
    END IF;
  END $
DELIMITER ;

Uso:

CALL drop_column_if_exists('my_table', 'my_column');

Ejemplo:

SELECT column_exists('my_table', 'my_column');       -- 1
CALL drop_column_if_exists('my_table', 'my_column'); -- success
SELECT column_exists('my_table', 'my_column');       -- 0
CALL drop_column_if_exists('my_table', 'my_column'); -- success
SELECT column_exists('my_table', 'my_column');       -- 0

La respuesta de Chase Seibert funciona, pero agregaría que si tiene varios esquemas desea alterar el SELECCIONAR así:

select * from information_schema.columns where table_schema in (select schema()) and table_name=...

Me doy cuenta de que este hilo es bastante antiguo ahora, pero estaba teniendo el mismo problema. Esta fue mi solución muy básica usando MySQL Workbench, pero funcionó bien ...

  1. obtenga un nuevo editor sql y ejecute SHOW TABLES para obtener una lista de sus tablas
  2. seleccione todas las filas y elija copiar al portapapeles (sin comillas) en el menú contextual
  3. pegue la lista de nombres en otra pestaña del editor
  4. escriba su consulta, es decir, ALTER TABLE x DROP a ;
  5. copie y pegue, de modo que termine con una consulta separada para cada tabla
  6. Alternar si el banco de trabajo debe detenerse cuando se produce un error
  7. Pulse ejecutar y mire a través del registro de salida

cualquier tabla que tenía la tabla ahora no tiene cualquier tabla que no haya mostrado un error en los registros

entonces puede encontrar / reemplazar 'soltar a ' cambiarlo a 'AGREGAR COLUMNA b INT NULO', etc. y ejecutar todo nuevamente ...

un poco torpe, pero al fin obtienes el resultado final y puedes controlar / monitorear todo el proceso y recuerda guardar tus scripts sql en caso de que los necesites nuevamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top