значения первичного ключа подкачки - PullRequest
14 голосов
/ 11 мая 2010

возможно ли поменять значения первичного ключа между двумя наборами данных? Если так, то как бы это сделать?

Ответы [ 3 ]

11 голосов
/ 11 мая 2010

Давайте для простоты предположим, что у вас есть две записи

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

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

оба из таблицы t (но они могут быть из разных таблиц)

Вы могли бы сделать

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

Примечание: Обновление первичных ключей имеет другие побочные эффекты, и, возможно, предпочтительным подходом было бы оставить первичные ключи такими, какие они есть, и поменять местами значения всех других столбцов.

Оговорка: Причина, по которой работает t.id = t2.id, t2.id = t.id, заключается в том, что в SQL обновление происходит на уровне транзакции. t.id не является переменной, а = не является присваиванием. Вы можете интерпретировать это как «установите t.id в значение, которое t2.id имел до эффекта запроса, установите t2.id в значение, которое t.id имел до эффекта запроса». Однако некоторые базы данных могут не обеспечивать надлежащую изоляцию, см., Например, этот вопрос (однако, выполнение вышеупомянутого запроса, который, вероятно, считается обновлением нескольких таблиц, вел себя в соответствии со стандартом в mysql).

5 голосов
/ 27 октября 2014

Я предпочитаю следующий подход (Джастин Кейв где-то написал подобное):

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)
1 голос
/ 18 ноября 2015

Аналогично решению @ Барта, но я использовал немного другой способ:

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

Это то же самое, но я знаю decode лучше, чем case.

Кроме того, чтобы решение @ Bart работало для меня, мне пришлось добавить when:

update t
set t.id = (case when t.id = 100 then 101 else 101 end)
where t.id in (100, 101);
...