【发布时间】:2012-09-06 14:50:49
【问题描述】:
sql swap primary key values 接受的答案失败并出现错误Can't reopen table: 't' - 大概这与打开同一个表写入两次导致锁定有关。
有什么捷径,还是我必须同时获得,将其中一个设置为NULL,将第二个设置为第一个,然后将第一个设置为先前获取的第二个值?
【问题讨论】:
标签: mysql
sql swap primary key values 接受的答案失败并出现错误Can't reopen table: 't' - 大概这与打开同一个表写入两次导致锁定有关。
有什么捷径,还是我必须同时获得,将其中一个设置为NULL,将第二个设置为第一个,然后将第一个设置为先前获取的第二个值?
【问题讨论】:
标签: mysql
不要为此使用临时表。
来自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 桌子?
要交换 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;
编辑:修正错误
【讨论】: