Här är en fungerande lösning (prevade precis med MySQL 5.0 på 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 ;
Vid en första anblick ser det förmodligen mer komplicerat ut än det borde, men vi måste hantera följande problem här:
IF
uttalanden fungerar bara i lagrade procedurer, inte när de körs direkt, t.ex. i mysql-klienten- mer elegant och koncis
SHOW COLUMNS
fungerar inte i lagrad procedur så måste använda INFORMATION_SCHEMA - syntaxen för att avgränsa satser är konstig i MySQL, så du måste omdefiniera avgränsaren för att kunna skapa lagrade procedurer. Glöm inte att byta tillbaka avgränsaren!
- INFORMATION_SCHEMA är global för alla databaser, glöm inte att filtrera på
TABLE_SCHEMA=DATABASE()
.DATABASE()
returnerar namnet på den för närvarande valda databasen.