¿Cómo se puede usar ALTER para colocar una columna en una tabla MySQL si esa columna existe?
Sé que puedo usarlo 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 de forma condicional?
Estoy usando MySQL versión 4.0.18.
Respuestas:
Para MySQL, no hay ninguno: MySQL Feature Request .
Permitir esto podría decirse que es una muy mala idea, de todos modos:
IF EXISTS
indica que está ejecutando operaciones destructivas en una base de datos con (para usted) una estructura desconocida. Puede haber situaciones en las que esto sea aceptable para un trabajo local rápido y sucio, pero si tiene la tentación de ejecutar una declaración de este tipo 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
es decir
ALTER TABLE my_table DROP IF EXISTS my_column;
Pero podría decirse que es una mala idea confiar en una función no estándar compatible con solo una de las varias bifurcaciones de MySQL.
fuente
No hay soporte de nivel de idioma para esto en MySQL. Aquí hay una solución que involucra a los metadatos de MySQL information_schema en 5.0+, pero no abordará 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 .
fuente
Sé que este es un hilo antiguo, pero hay una forma sencilla de manejar este requisito sin utilizar 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 a mí (después de mucho ensayo y error).
fuente
Acabo de construir un procedimiento reutilizable que puede ayudar a
DROP COLUMN
volverse 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
fuente
La respuesta de Chase Seibert funciona, pero agregaría que si tiene varios esquemas, desea alterar SELECT de esta manera:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
fuente
Quizás la forma más sencilla de resolver esto (que funcionará) es:
CREAR new_table AS SELECT id, col1, col2, ... (solo las columnas que realmente desea en la tabla final) FROM my_table;
CAMBIAR EL NOMBRE my_table TO old_table, new_table TO my_table;
DROP old_table;
O mantenga old_table para una reversión si es necesario.
Esto funcionará, pero las claves externas no se moverán. Tendría que volver a agregarlos a my_table más tarde; también las claves externas en otras tablas que hacen referencia a my_table tendrán que ser arregladas (señaladas a la nueva my_table).
Buena suerte...
fuente
Puede usar este script, usar su columna, esquema y nombre de tabla
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName' AND TABLE_SCHEMA = SchemaName) BEGIN ALTER TABLE TableName DROP COLUMN ColumnName; END;
fuente
Me doy cuenta de que este hilo es bastante antiguo ahora, pero yo estaba teniendo el mismo problema. Esta fue mi solución muy básica usando MySQL Workbench, pero funcionó bien ...
x
DROPa
;cualquier tabla que tenía la tabla ahora no tiene ninguna tabla que no haya mostrado un error en los registros
luego puede buscar / reemplazar 'soltar
a
' cambiarlo a 'AGREGAR COLUMNAb
INT NULL', etc. y ejecutar todo nuevamente ...un poco torpe, pero al final obtiene el resultado final y puede controlar / monitorear todo el proceso y recordar guardar sus scripts sql en caso de que los necesite nuevamente.
fuente