2016-11-21 81 views
0

有人可以告訴我爲什麼會發生這種情況。原始問題一如既往地複雜得多,但我創建了一個簡單的測試用例來重現問題。首先,你需要一個表像這樣:SQL無法在更改其他列後更改主鍵列名稱

CREATE TABLE `test` (
    `test_a` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `test_b` int(11) DEFAULT NULL, 
    PRIMARY KEY (`test_a`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

然後,你需要嘗試修改表與此查詢:

ALTER TABLE `test` 
    CHANGE COLUMN `test_b` `new_test_b` INT(11) NOT NULL AFTER `test_a`, 
    CHANGE COLUMN `test_a` `new_test_a` INT(11) NOT NULL AUTO_INCREMENT FIRST; 

,你會得到這樣的結果:

Unknown column 'test_a' in 'test' 

我不沒辦法。當你分別進行每個改動時,它可以正常工作,但如果你一起做它,它就會爆炸。


編...

這個研究了一下之後,我想通了一些事情。我猜測編譯器(或預處理器或某事)正在以相反順序評估以逗號分隔的alter語句,在那裏 - 通過在獲取test_b之前更改test_a列名稱(這會使'AFTER test_a'部分不成立道理..事實證明,這是因爲如果顛倒像這樣的語句的順序是錯誤的測試:

ALTER TABLE `test 
    CHANGE COLUMN `test_a` `new_test_a` INT(11) NOT NULL AUTO_INCREMENT FIRST, 
    CHANGE COLUMN `test_b` `new_test_b` INT(11) NOT NULL AFTER `test_a`; 

你同樣的結果結束了

接下來我把假設某操作類型優先於此類聲明我假定所有CHANGE COLUMN操作都必須在任何列順序操作之前發生,例如'AFTER test_a'如果是這種情況,那麼這將是有意義的排序操作引用新列的名稱,就像這樣:

ALTER TABLE `test` 
    CHANGE COLUMN `test_b` `new_test_b` INT(11) NOT NULL AFTER `new_test_a`, 
    CHANGE COLUMN `test_a` `new_test_a` INT(11) NOT NULL AUTO_INCREMENT FIRST; 

這個工作。所以這一定是答案。我想我的問題現在已經演變爲各種類型的操作的優先順序。

請注意,對不起,我不打算標記任何當前的答案正確,因爲他們實際上沒有回答問題,他們只是提供替代方法來做同樣的事情(或說明顯而易見)。

+2

這可能是因爲它是第一個重命名的種皮,因爲在第一個ALTER語句上測試的依賴,然後試着種皮後修改TESTB。但是因爲testa現在被重命名,所以錯誤。但是你需要檢查alter的文檔是100%確定的。 – Swetha

+0

這是最接近我認爲的答案,因此upvote –

回答

0

你可以這樣來做:

ALTER TABLE `test` 
    CHANGE COLUMN `test_b` `new_test_b` INT(11) NOT NULL AFTER `test_a`; 
ALTER TABLE `test` 
    CHANGE COLUMN `test_a` `new_test_a` INT(11) NOT NULL AUTO_INCREMENT FIRST; 
+0

是的,他已經這樣做了,似乎 – e4c5