【问题标题】:MySQL swap primary key valuesMySQL交换主键值
【发布时间】:2012-09-06 14:50:49
【问题描述】:

sql swap primary key values 接受的答案失败并出现错误Can't reopen table: 't' - 大概这与打开同一个表写入两次导致锁定有关。

有什么捷径,还是我必须同时获得,将其中一个设置为NULL,将第二个设置为第一个,然后将第一个设置为先前获取的第二个值?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    不要为此使用临时表。

    来自manual

    您不能在同一查询中多次引用 TEMPORARY 表。 例如,以下内容不起作用:

    mysql> SELECT * FROM temp_table, temp_table AS t2;
    ERROR 1137: Can't reopen table: 'temp_table'
    

    如果多次引用临时表也会出现此错误 在不同别名下的存储函数中的时间,即使 引用出现在函数内的不同语句中。

    更新:

    对不起,如果我没有理解正确,但为什么简单的三向交换不起作用?

    像这样:

    create table yourTable(id int auto_increment, b int, primary key(id));
    
    insert into yourTable(b) values(1), (2);
    select * from yourTable;
    
    DELIMITER $$
    create procedure pkswap(IN a int, IN b int)
    BEGIN
    select @max_id:=max(id) + 1 from yourTable;
    update yourTableset id=@max_id where id = a;
    update yourTableset id=a where id = b;
    update yourTableset id=b where id = @max_id;
    END $$
    DELIMITER ;
    
    call pkswap(1, 2);
    
    select * from yourTable;
    

    【讨论】:

    • 谁提到了TEMPORARY 桌子?
    • 好吧,使用非临时表,我收到错误“键的重复条目”。
    • 嗯,当三路交换可以更轻松地完成时,需要做很多工作......
    • 请多解释一下您的问题。我不明白。
    • 这里有很多工作吗?您创建一次过程并在需要时调用它。另外,这个解决方案是傻瓜证明。
    【解决方案2】:

    要交换 1 和 2 的 id 值,我会使用如下 SQL 语句:

    编辑: 根据我的测试,这不适用于 InnoDB 表,仅适用于 MyISAM 表。 罢工>

    UPDATE mytable a 
      JOIN mytable b ON a.id = 1 AND b.id = 2 
      JOIN mytable c ON c.id = a.id
       SET a.id = 0
         , b.id = 1
         , c.id = 2 
    

    要使该语句起作用,表中不能存在 0 的 id 值,任何未使用的值都适合...但是要使其在单个 SQL 语句中起作用,您需要(暂时)使用第三个 id 值。


    此解决方案适用于常规 MyISAM 表,而不适用于临时表。我错过了这是在临时表上执行的,我对您报告的错误消息 Can't reopen table: 感到困惑。

    要在临时表中交换 id 值 1 和 2,我将再次运行三个单独的语句,使用临时占位符值 0:

    UPDATE mytable a SET a.id = 0 WHERE a.id = 1;
    UPDATE mytable b SET b.id = 1 WHERE b.id = 2;
    UPDATE mytable c SET c.id = 2 WHERE c.id = 0;
    

    编辑:修正错误

    【讨论】:

    • @Kolink:我在 InnoDB 表上进行了测试,你是对的。该语句确实适用于 MyISAM 表。我推荐三语句方法,它应该适用于 MyISAM、InnoDB 和临时(也是 MyISAM)表。实际上,我对 InnoDB 的测试表明 1 变为 0,2 变为 1,然后 1 再次变回 2……使用 MyISAM 进行测试会产生不同的结果。
    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    相关资源
    最近更新 更多