3 回答

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超2個(gè)贊
請(qǐng)注意,INFORMATION_SCHEMA5.0之前的MySQL不支持。5.0之前也不支持存儲(chǔ)過程,所以如果你需要支持MySQL 4.1,這個(gè)解決方案并不好。
使用數(shù)據(jù)庫遷移的框架使用的一種解決方案是在數(shù)據(jù)庫中記錄模式的修訂號(hào)。只是一個(gè)包含單列和單行的表,其中一個(gè)整數(shù)表示哪個(gè)版本是當(dāng)前有效的。更新架構(gòu)時(shí),請(qǐng)遞增數(shù)字。
另一種解決方案是只嘗試的ALTER TABLE ADD COLUMN命令。如果列已存在,則應(yīng)該拋出錯(cuò)誤。
ERROR 1060 (42S21): Duplicate column name 'newcolumnname'
在升級(jí)腳本中捕獲錯(cuò)誤并忽略它。

TA貢獻(xiàn)1871條經(jīng)驗(yàn) 獲得超8個(gè)贊
這是一個(gè)可行的解決方案(剛剛在Solaris上使用MySQL 5.0):
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 ;
乍一看,它可能看起來比它應(yīng)該更復(fù)雜,但我們必須在這里處理以下問題:
IF 語句只能在存儲(chǔ)過程中使用,而不能直接運(yùn)行,例如在mysql客戶端中
更優(yōu)雅和簡潔SHOW COLUMNS在存儲(chǔ)過程中不起作用,因此必須使用INFORMATION_SCHEMA
在MySQL中,分隔語句的語法很奇怪,因此您必須重新定義分隔符才能創(chuàng)建存儲(chǔ)過程。不要忘記切換分隔符!
INFORMATION_SCHEMA是所有數(shù)據(jù)庫的全局,不要忘記過濾TABLE_SCHEMA=DATABASE()。DATABASE()返回當(dāng)前所選數(shù)據(jù)庫的名稱。

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
大多數(shù)答案都解決了如何在存儲(chǔ)過程中安全地添加列,我需要在不使用存儲(chǔ)過程的情況下安全地向表添加列,并發(fā)現(xiàn)MySQL不允許在SPIF Exists()外部使用。我會(huì)發(fā)布我的解決方案,它可能會(huì)幫助處于相同情況的人。
SELECT count(*)
INTO @exist
FROM information_schema.columns
WHERE table_schema = database()
and COLUMN_NAME = 'original_data'
AND table_name = 'mytable';
set @query = IF(@exist <= 0, 'alter table intent add column mycolumn4 varchar(2048) NULL after mycolumn3',
'select \'Column Exists\' status');
prepare stmt from @query;
EXECUTE stmt;
添加回答
舉報(bào)