1

sql swap primary key valuesに対する受け入れられた回答は、エラーで失敗します。Can't reopen table: 't'おそらく、これは、同じテーブルを 2 回書き込むために開いて、ロックを引き起こしていることに関係しています。

ショートカットはありますか、または両方を取得し、それらNULLの1つを に設定し、2番目のものを最初のものに設定し、最初のものを以前に取得した2番目の値に設定する必要がありますか?

4

2 に答える 2

1

これには一時テーブルを使用しないでください。

マニュアルから:

同じクエリで 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;
于 2012-09-06T15:00:46.007 に答える
0

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;

編集:修正されたエラー

于 2012-09-06T15:35:01.057 に答える