Je bent eigenlijk op zoek naar een Invoeg- of Updatepatroon soms aangeduid als een Upsert.
Ik raad dit aan:patroon voor SQL Server invoegen of bijwerken - Sam Saffron
Voor een procedure die te maken heeft met enkele rijen, zouden deze transacties goed werken:
Sam Saffron's eerste oplossing (aangepast voor dit schema):
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
De tweede oplossing van Sam Saffron (aangepast voor dit schema):
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
Zelfs met creatief gebruik van IGNORE_DUP_KEY
, zit je nog steeds vast met het gebruik van een insert/update block of een merge-statement.
- Een creatief gebruik van IGNORE_DUP_KEY - Paul White @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'
);
Het Merge-antwoord van Spock zou moeten doen wat je wilt.
Samenvoegen is niet per se aan te raden. Ik gebruik het, maar ik zou dat nooit toegeven aan @AaronBertrand.
-
Wees voorzichtig met de MERGE-instructie van SQL Server - Aaron Bertrand
-
Kan ik deze samenvoegverklaring optimaliseren - Aaron Bertrand
-
Als u geïndexeerde weergaven en MERGE gebruikt, lees dit dan alstublieft! - Aaron Bertrand
-
Een interessante MERGE-bug - Paul White
-
UPSERT-raceconditie met samenvoegen