2010-05-11 34 views
13

có thể hoán đổi các giá trị khóa chính giữa hai bộ dữ liệu không? Nếu vậy, làm thế nào một trong những sẽ làm điều đó?sql trao đổi giá trị khóa chính

+0

Tôi cũng không có ý tưởng gì, cụ thể, bạn đang cố gắng đạt được. – bmargulies

+1

Tại sao bạn muốn làm điều đó? Bạn không thích các khóa chính của bạn? ;) –

+0

Và có, có thể. Ví dụ, trong perl có fetchall_hashref chấp nhận bất kỳ tên cột nào được sử dụng. – Konerak

Trả lời

10

Hãy vì lợi ích của sự đơn giản giả sử bạn có hai kỷ lục

id name 
--------- 
1 john 

id name 
--------- 
2 jim 

cả từ bảng t (nhưng họ có thể đến từ các bảng khác nhau)

Bạn có thể làm

UPDATE t, t as t2 
SET t.id = t2.id, t2.id = t.id 
WHERE t.id = 1 AND t2.id = 2 

Note : Cập nhật các khóa chính có các tác dụng phụ khác và có thể cách tiếp cận ưa thích sẽ là để lại các khóa chính như chúng và trao đổi các giá trị của tất cả các thứ e các cột khác.

Lưu ý: Lý do tại sao các hoạt động t.id = t2.id, t2.id = t.id là do trong SQL cập nhật xảy ra ở cấp giao dịch. t.id không thay đổi và = không được gán. Bạn có thể giải thích nó là "set t.id thành giá trị t2.id có trước hiệu ứng của truy vấn, đặt t2.id thành giá trị t.id trước khi có hiệu lực của truy vấn". Tuy nhiên, một số cơ sở dữ liệu có thể không làm cách ly thích hợp, xem ví dụ này question (tuy nhiên, chạy trên truy vấn, có thể được coi là cập nhật nhiều bảng, hoạt động theo tiêu chuẩn trong mysql).

+0

cảm ơn rất nhiều bất tiện! – Thomas

+0

Không có trong MySQL 5.1.62 với 'ERROR 1062 (23000): Mục nhập trùng lặp '2' cho khóa 'PRIMARY''. – dotancohen

+2

Giải pháp của bạn không hoạt động trong MySQL 5.5.22-log: '1706 - Không cho phép cập nhật khóa chính/phân vùng chính vì bảng được cập nhật cả dưới dạng 'lae_marketing_invoice_history' và 't2'.' –

5

Tôi thích cách tiếp cận sau (Justin Cave viết tương tự ở đâu đó):

update MY_TABLE t1 
set t1.MY_KEY = (case when t1.MY_KEY = 100 then 101 else 100 end) 
where t1.MYKEY in (100, 101) 
+0

Đặt các giá trị khóa thô dưới dạng chữ trong truy vấn giải quyết vấn đề của các khóa trùng lặp trong quá trình giao dịch. –

1

Tương tự như @ giải pháp Bart, nhưng tôi đã sử dụng một cách hơi khác nhau:

update t 
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual) 
where t.id in (100, 101); 

này khá giống nhau , nhưng tôi biết decode tốt hơn thì case.

Ngoài ra, để thực hiện công việc @ giải pháp Bart cho tôi, tôi đã có thêm một when:

update t 
set t.id = (case when t.id = 100 then 101 else 101 end) 
where t.id in (100, 101); 
Các vấn đề liên quan