Aquí hay una solución que funciona (recién probada con MySQL 5.0 en Solaris):
DELIMITER $$
DROP PROCEDURE IF EXISTS upgrade_database_1_0_to_2_0 $$
CREATE PROCEDURE upgrade_database_1_0_to_2_0()
BEGIN
-- rename a table safely
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
AND TABLE_NAME='my_old_table_name') ) THEN
RENAME TABLE
my_old_table_name TO my_new_table_name,
END IF;
-- add a column safely
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
AND COLUMN_NAME='my_additional_column' AND TABLE_NAME='my_table_name') ) THEN
ALTER TABLE my_table_name ADD my_additional_column varchar(2048) NOT NULL DEFAULT '';
END IF;
END $$
CALL upgrade_database_1_0_to_2_0() $$
DELIMITER ;
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, p. en el cliente mysql- más elegante y conciso
SHOW COLUMNS
no funciona en el procedimiento almacenado, por lo que debe usar INFORMATION_SCHEMA - la sintaxis para delimitar declaraciones es extraña en MySQL, por lo que debe redefinir el delimitador para poder crear procedimientos almacenados. ¡No olvide volver a cambiar el delimitador!
- INFORMATION_SCHEMA es global para todas las bases de datos, no olvide filtrar en
TABLE_SCHEMA=DATABASE()
.DATABASE()
devuelve el nombre de la base de datos actualmente seleccionada.