2016-06-07 47 views
0

我有一個表ID,一個PK ID和一個帶有一些文本的varchar(20)。該PK也是另一個表中的FK 我試圖切換兩行之間的ID,但我一直無法這樣做,因爲MySQl可以防止這種情況與原子上的FK約束錯誤,該行將違反FK限制,但只有一個毫秒,因爲我會使該ID再次與另一行一起存在。 例如MySQL在一個原子動作中更新兩行

表1

ID varchar(10) 
1 "Hello" 
2 "Bye" 

表2

1(PK,FK) "Another data" 
2(PK,FK) "BLA" 

如果我

UPDATE Table 1 set ID=1 where text="Bye"; 
UPDATE Table 1 set ID=2 where text="Hello"; 

它將作爲失敗

  1. ID已經存在
  2. 它會違反FK約束。

我該怎麼做?

編輯:我必須這樣做一次,但對於一堆行,因爲有人沒有添加一些需要在特定索引中的數據。使用中間值將修復1,但仍會違反FK約束。發佈的答案不談論FK。

+0

是要做這個東西是需要經常或只是一個罕見的數據修復?如果是這樣,你可能想要回顧爲什麼你必須這樣做。 – SQLChao

+0

可能重複的[在數據庫中交換唯一索引列值](http://stackoverflow.com/questions/644/swap-unique-indexed-column-values-in-database) – Edu

+0

也可能重複http:// stackoverflow的.com /問題/ 12302745/MySQL的交換 - 主鍵值的 – Edu

回答

1

你可以嘗試換`表1`的文本內容,而不是這將使作爲交換它們的ID相同的效果。像下面

START TRANSACTION; 
SET @text1 := 'Hello', @text2 := 'Bye'; 
SELECT @id1 := ID FROM `Table 1` WHERE [email protected]; 
SELECT @id2 := ID FROM `Table 1` WHERE [email protected]; 
UPDATE `Table 1` SET [email protected] WHERE ID = @id2; 
UPDATE `Table 1` SET [email protected] WHERE ID = @id1; 
COMMIT; 

http://sqlfiddle.com/#!9/f287cd/1

如果您對文本唯一約束...您可以使用此

START TRANSACTION; 
SET @text1 := 'Hello', @text2 := 'Bye'; 
SELECT @id1 := ID FROM `Table 1` WHERE [email protected]; 
SELECT @id2 := ID FROM `Table 1` WHERE [email protected]; 
UPDATE `Table 1` SET text=NULL WHERE ID = @id2; 
UPDATE `Table 1` SET [email protected] WHERE ID = @id1; 
UPDATE `Table 1` SET [email protected] WHERE ID = @id2; 
COMMIT; 

http://sqlfiddle.com/#!9/a3d49/1

1

簡單的解決方法:使用中間值。

UPDATE Table 1 set ID=0 where text="Hello"; 
UPDATE Table 1 set ID=1 where text="Bye"; 
UPDATE Table 1 set ID=2 where text="Hello"; 
1

試試這個:

UPDATE Table1 SET text="new value" where id=1