По същество търсите шаблон за вмъкване или актуализиране понякога се нарича Upsert.
Препоръчвам това:Вмъкване или актуализиране на шаблон за Sql сървър - Sam Saffron
За процедура, която ще се занимава с единични редове, тези транзакции ще работят добре:
Първото решение на Сам Шафран (адаптирано за тази схема):
begin tran
if exists (
select *
from mytable with (updlock,serializable)
where col_a = @val_a
and col_b = @val_b
and col_c = @val_c
)
begin
update mytable
set col_d = @val_d
where col_a = @val_a
and col_b = @val_b
and col_c = @val_c;
end
else
begin
insert into mytable (col_a, col_b, col_c, col_d)
values (@val_a, @val_b, @val_c, @val_d);
end
commit tran
Второто решение на Сам Шафран (адаптирано за тази схема):
begin tran
update mytable with (serializable)
set col_d = @val_d
where col_a = @val_a
and col_b = @val_b
and col_c = @val_c;
if @@rowcount = 0
begin
insert into mytable (col_a, col_b, col_c, col_d)
values (@val_a, @val_b, @val_c, @val_d);
end
commit tran
Дори с креативно използване на IGNORE_DUP_KEY
, все още ще се налага да използвате блок за вмъкване/актуализация или оператор за сливане.
- Креативно използване на IGNORE_DUP_KEY - Пол Уайт @Sql_Kiwi
update mytable
set col_d = 'val_d'
where col_a = 'val_a'
and col_b = 'val_b'
and col_c = 'val_c';
insert into mytable (col_a, col_b, col_c, col_d)
select 'val_a','val_b', 'val_c', 'val_d'
where not exists (select *
from mytable with (serializable)
where col_a = 'val_a'
and col_b = 'val_b'
and col_c = 'val_c'
);
Отговорът за сливане, предоставен от Спок, трябва да прави това, което искате.
Обединяване не се препоръчва непременно. Използвам го, но никога не бих признал това на @AaronBertrand.
-
Бъдете внимателни с изявлението MERGE на SQL Server - Аарон Бертран
-
Мога ли да оптимизирам това изявление за сливане - Aaron Bertrand
-
Ако използвате индексирани изгледи и MERGE, моля, прочетете това! - Аарон Бертран
-
Интересен бъг за MERGE - Пол Уайт
-
UPSERT Състояние на състезанието със сливане