Возможно ли обменять первичные значения ключей между двумя наборами данных? Если да, то как это сделать?значения первичного ключа свопа sql
ответ
Давайте для простоты предположим, у вас есть две записи
id name
---------
1 john
id name
---------
2 jim
как из таблицы т (но они могут поступать из разных таблиц)
Вы могли бы сделать
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, имевшееся до эффекта запроса». Тем не менее, некоторые базы данных могут не выполнять надлежащую изоляцию, например, это question (однако, работа над запросом, который, вероятно, считается обновлением нескольких таблиц, вел себя в соответствии со стандартом в mysql).
благодарит много неразумных! – Thomas
Ошибка в MySQL 5.1.62 с 'ERROR 1062 (23000): Дублировать запись '2' для ключа 'PRIMARY''. – dotancohen
Ваше решение не работает в MySQL 5.5.22-log: '1706 - Обновление основного ключа/раздела не разрешено, так как таблица обновляется как« lae_marketing_invoice_history »и« t2 ». –
Я предпочитаю следующий подход (Justin Cave писал похоже где-то):
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)
Ввод значений исходного ключа в качестве литералов в запросе решает проблема дублирования ключей во время транзакции. –
Подобно @ решения Барта, но я использовал несколько иначе:
update t
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual)
where t.id in (100, 101);
Это совершенно то же самое , но я знаю decode
лучше, чем case
.
Кроме того, чтобы сделать @ работу решения Барта мне пришлось добавить when
:
update t
set t.id = (case when t.id = 100 then 101 else 101 end)
where t.id in (100, 101);
я понятия не имею, что, в деталях, вы пытаетесь достичь. – bmargulies
Зачем вам это нужно? Вам не нравятся ваши первичные ключи? ;) –
И да, это возможно. Например, в perl есть fetchall_hashref, который принимает любое имя столбца, которое будет использоваться. – Konerak