Используются следующие таблицы:
Table Product:
product_id
merged_product_id
product_name
Table Company_Product:
product_id
company_id
(Company_Product имеет первичный ключ в столбцах product_id и company_id)
Теперь я хочу запустить обновление Company_Product, чтобы установить для столбца product_id значение merged_ product_id. Это обновление может вызвать дубликаты, которые вызовут нарушение первичного ключа, поэтому я добавил проверку «не существует» в предложении where, и мой запрос выглядит так:
update cp
set cp.product_id = p.merged_product_id
from Company_Product cp
join Product p on p.product_id = cp.product_id
where p.merged_product_id is not null
and not exists
(select * from Company_Product cp2
where cp2.company_id = cp.company_id and
cp2.product_id = p.merged_product_id)
Но этот запрос не выполняется с нарушением первичного ключа.
Я думаю, что это может произойти из-за того, что таблица Product содержит несколько строк с одинаковым merged_product_id, она заменится для первого продукта, но при переходе к следующему продукту с тем же merged_product_id произойдет сбой, потому что не существует 'подзапрос не видит первое изменение, так как запрос еще не завершен и не зафиксирован.
Правильно ли я думаю об этом, и как бы я изменил запрос, чтобы он работал?
[EDIT] Некоторые примеры данных:
Product:
product_id merged_product_id
23 35
24 35
25 12
26 35
27 NULL
Company_Product:
product_id company_id
23 2
24 2
25 2
26 3
27 4
[РЕДАКТИРОВАТЬ 2] В конце концов я пошел с этим решением, которое использует временную таблицу для обновления, а затем вставляет обновленные данные в исходную таблицу Company_Product:
create table #Company_Product
(product_id int, company_id int)
insert #Company_Product select * from Company_Product
update cp
set cp.product_id = p.merged_product_id
from #Company_Product cp
join Product p on p.product_id = cp.product_id
where p.merged_product_id is not null
delete from Company_Product
insert Company_Product select distinct * from #Company_Product
drop table #Company_Product