sql >> Databasteknik >  >> RDS >> Sqlserver

Motsvarighet till MySQL PÅ DUPLIKATNYCKELUPPDATERING i SQL Server

Du letar i princip efter ett Infoga eller uppdatera mönster kallas ibland för en Upsert.

Jag rekommenderar detta:Infoga eller uppdatera mönster för SQL Server - Sam Saffron

För en procedur som kommer att hantera enstaka rader, skulle antingen dessa transaktioner fungera bra:

Sam Saffrons första lösning (anpassad för detta 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

Sam Saffrons andra lösning (anpassad för detta 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

Även med en kreativ användning av IGNORE_DUP_KEY , skulle du fortfarande vara tvungen att använda ett infognings-/uppdateringsblock eller en sammanfogningssats.

  • En kreativ användning av 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 från Spock bör göra vad du vill.

Slå samman rekommenderas inte nödvändigtvis. Jag använder det, men jag skulle aldrig erkänna det för @AaronBertrand.

  • Var försiktig med SQL Servers MERGE-uttalande - Aaron Bertrand

  • Kan jag optimera detta sammanslagningsförklaring - Aaron Bertrand

  • Om du använder indexerade vyer och MERGE, läs detta! - Aaron Bertrand

  • En intressant MERGE Bug - Paul White

  • UPSERT Race Condition With Merge



  1. Hur får man flera räkningar med en SQL-fråga?

  2. NEW_TIME() Funktion i Oracle

  3. Hur tar man bort från flera tabeller i MySQL?

  4. FEL:det finns ingen unik begränsning som matchar givna nycklar för refererad tabellstapel