2016-11-21 31 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