Du leder grundlæggende efter et Indsæt eller Opdater mønster nogle gange omtalt som en upsert.
Jeg anbefaler dette:Indsæt eller opdater mønster for SQL Server - Sam Saffron
For en procedure, der vil beskæftige sig med enkelte rækker, ville enten disse transaktioner fungere godt:
Sam Saffrons første løsning (tilpasset til dette skema):
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
Sam Saffrons anden løsning (tilpasset til dette skema):
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
Selv med en kreativ brug af IGNORE_DUP_KEY
, vil du stadig sidde fast ved at skulle bruge en indsæt-/opdateringsblok eller en flettesætning.
- En kreativ brug af 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'
);
Merge-svaret fra Spock bør gøre, hvad du vil.
Flet anbefales ikke nødvendigvis. Jeg bruger det, men jeg ville aldrig indrømme det over for @AaronBertrand.
-
Vær forsigtig med SQL Servers MERGE-erklæring - Aaron Bertrand
-
Kan jeg optimere denne fusionserklæring - Aaron Bertrand
-
Hvis du bruger indekserede visninger og FLET, så læs venligst dette! - Aaron Bertrand
-
En interessant fusionsfejl - Paul White
-
UPSERT Race Condition With Merge