sql swap primary key valuesに対する受け入れられた回答は、エラーで失敗します。Can't reopen table: 't'
おそらく、これは、同じテーブルを 2 回書き込むために開いて、ロックを引き起こしていることに関係しています。
ショートカットはありますか、または両方を取得し、それらNULL
の1つを に設定し、2番目のものを最初のものに設定し、最初のものを以前に取得した2番目の値に設定する必要がありますか?
sql swap primary key valuesに対する受け入れられた回答は、エラーで失敗します。Can't reopen table: 't'
おそらく、これは、同じテーブルを 2 回書き込むために開いて、ロックを引き起こしていることに関係しています。
ショートカットはありますか、または両方を取得し、それらNULL
の1つを に設定し、2番目のものを最初のものに設定し、最初のものを以前に取得した2番目の値に設定する必要がありますか?
これには一時テーブルを使用しないでください。
マニュアルから:
同じクエリで TEMPORARY テーブルを複数回参照することはできません。たとえば、次は機能しません。
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
このエラーは、関数内の異なるステートメントで参照が発生した場合でも、ストアド関数で異なるエイリアスの下で一時テーブルを複数回参照した場合にも発生します。
アップデート:
正しく理解できていない場合は申し訳ありませんが、単純な 3 者間交換が機能しないのはなぜですか?
このような:
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;
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 ステートメントで機能させるには、(一時的に) 3 番目の ID 値を使用する必要があります。 .
このソリューションは、一時テーブルではなく、通常の MyISAM テーブルで機能します。これが一時テーブルで実行されていることを見逃していました。報告されたエラー メッセージに混乱しましたCan't reopen table:
。
一時テーブルで id 値 1 と 2 を入れ替えるには、ここでも一時プレースホルダー値 0 を使用して、3 つの個別のステートメントを実行します。
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;
編集:修正されたエラー