【问题标题】:SQL Cant change primary key column name after changing other column更改其他列后SQL无法更改主键列名
【发布时间】:2016-11-21 23:16:59
【问题描述】:

谁能告诉我为什么会这样。最初的问题总是要复杂得多,但我创建了一个简单的测试用例来重现该问题。首先你需要一个像这样的表:

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;

这行得通。所以这一定是答案。我想我的问题现在已经演变为各种操作的优先顺序是什么。

请注意,抱歉,我不会将任何当前答案标记为正确,因为它们实际上并没有回答问题,它们只是提供替代方法来做同样的事情(或说明显而易见的事情)。

【问题讨论】:

  • 这可能是因为它首先重命名 testa 因为在第一个 alter 语句中存在对 test a 的依赖,然后尝试在 testa 之后修改 testb 。但是由于 testa 现在已重命名,因此出现错误。但是您需要检查 alter 的文档以 100% 确定。
  • 这是最接近我认为的答案,因此赞成

标签: mysql primary-key alter-table


【解决方案1】:

你可以这样做:

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多