Mi investigación y experimentos aún no han dado una respuesta, por lo que espero recibir ayuda.
Estoy modificando el archivo de instalación de una aplicación que en versiones anteriores no tenía una columna que quiero agregar ahora. No quiero agregar la columna manualmente, sino en el archivo de instalación y solo si la nueva columna no existe en la tabla.
La tabla se crea de la siguiente manera:
CREATE TABLE IF NOT EXISTS `#__comm_subscribers` (
`subscriber_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL default '0',
`subscriber_name` varchar(64) NOT NULL default '',
`subscriber_surname` varchar(64) NOT NULL default '',
`subscriber_email` varchar(64) NOT NULL default '',
`confirmed` tinyint(1) NOT NULL default '0',
`subscribe_date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`subscriber_id`),
UNIQUE KEY `subscriber_email` (`subscriber_email`)
) ENGINE=MyISAM CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' COMMENT='Subscribers for Comm are stored here.';
Si agrego lo siguiente, debajo de la declaración de creación de la tabla, entonces no estoy seguro de qué sucede si la columna ya existe (y tal vez está poblada):
ALTER TABLE `#__comm_subscribers` ADD `subscriber_surname`;
ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';
Entonces, probé lo siguiente que encontré en alguna parte. Esto no parece funcionar, pero no estoy completamente seguro de haberlo utilizado correctamente.
/*delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='subscriber_surname' AND TABLE_NAME='#__comm_subscribers'
)
THEN
ALTER TABLE `#__comm_subscribers`
ADD COLUMN `subscriber_surname` varchar(64) NOT NULL default '';
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;*/
¿Alguien tiene una buena manera de hacer esto?
Respuestas:
Tenga en cuenta que
INFORMATION_SCHEMA
no es compatible con MySQL antes de 5.0. Los procedimientos almacenados tampoco son compatibles con versiones anteriores a 5.0, por lo que si necesita admitir MySQL 4.1, esta solución no es buena.Una solución utilizada por los frameworks que utilizan migraciones de bases de datos es registrar en su base de datos un número de revisión para el esquema. Solo una tabla con una sola columna y una sola fila, con un número entero que indica qué revisión está vigente. Cuando actualice el esquema, incremente el número.
Otra solución sería simplemente probar el
ALTER TABLE ADD COLUMN
comando. Debería arrojar un error si la columna ya existe.Detecte el error e ignórelo en su script de actualización.
fuente
--force
cambio, lo que significa que continúe incluso si hay un error. entonces, hazlo. solo desea asegurarse de que no haya declaraciones que NO desee que tengan éxito si algo anterior ha fallado.Aquí hay una solución que funciona (acaba de probar con MySQL 5.0 en Solaris):
A primera vista, probablemente parezca más complicado de lo que debería, pero aquí tenemos que lidiar con los siguientes problemas:
IF
Las declaraciones solo funcionan en procedimientos almacenados, no cuando se ejecutan directamente, por ejemplo, en el cliente mysqlSHOW COLUMNS
no funciona en el procedimiento almacenado, por lo que debe usar INFORMATION_SCHEMATABLE_SCHEMA=DATABASE()
.DATABASE()
devuelve el nombre de la base de datos actualmente seleccionada.fuente
Si está en MariaDB, no es necesario utilizar procedimientos almacenados. Solo usa, por ejemplo:
Mira aquí
fuente
La mayoría de las respuestas abordan cómo agregar una columna de forma segura en un procedimiento almacenado, tuve la necesidad de agregar una columna a una tabla de manera segura sin usar un proceso almacenado y descubrí que MySQL no permite el uso de
IF Exists()
un SP externo . Publicaré mi solución que podría ayudar a alguien en la misma situación.fuente
Otra forma de hacer esto sería ignorar el error con
declare continue handler
:Creo que es más ordenado de esta manera que con una
exists
subconsulta. Especialmente si tiene muchas columnas para agregar y desea ejecutar el script varias veces.se puede encontrar más información sobre los controladores continuos en http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
fuente
Estoy usando MySQL 5.5.19.
Me gusta tener scripts que se pueden ejecutar y volver a ejecutar sin errores, especialmente cuando las advertencias parecen persistir, apareciendo de nuevo más tarde mientras ejecuto scripts que no tienen errores / advertencias. En lo que respecta a la adición de campos, escribí un procedimiento para hacerlo un poco menos tipeado:
El código para crear el procedimiento addFieldIfNotExists es el siguiente:
No escribí un procedimiento para modificar de forma segura una columna, pero creo que el procedimiento anterior podría modificarse fácilmente para hacerlo.
fuente
Tomé el sproc del OP y lo hice reutilizable e independiente del esquema. Obviamente, todavía requiere MySQL 5.
fuente
Probé el script de procedimiento almacenado. Parece que el problema son las
'
marcas alrededor de los delimitadores. Los documentos de MySQL muestran que los caracteres delimitadores no necesitan las comillas simples.Entonces quieres:
En vez de:
Funciona para mi :)
fuente
Si está ejecutando esto en un script, querrá agregar la siguiente línea después para que se pueda volver a ejecutar; de lo contrario, obtendrá un error de procedimiento ya existente.
fuente
La mejor manera de agregar la columna en PHP> PDO:
Nota: la columna en la tabla no es repetible, eso significa que no necesitamos verificar la existencia de una columna, pero para resolver el problema verificamos el código anterior:
por ejemplo, si funciona alerta 1, si no 0, ¡lo que significa que la columna existe! :)
fuente
Compruebe si la columna existe o no en PDO (100%)
fuente
El procedimiento de Jake https://stackoverflow.com/a/6476091/6751901 es una solución muy simple y buena para agregar nuevas columnas, pero con una línea adicional:
puede agregar nuevas columnas más adelante allí, y también funcionará la próxima vez:
fuente
Luego, en $ res por ciclo, busque la clave de su columna Smth así:
fuente
SHOW fields FROM __TABLE__NAME__ where field='_my_col_';
y luego verificar que el conjunto de resultados no esté vacíoA continuación se muestra el procedimiento almacenado en MySQL para agregar columnas en diferentes tablas en diferentes bases de datos si la columna no existe en una (s) tabla (s) de base de datos con las siguientes ventajas
fuente
fuente