SQL Server 2005 Wdrożenie MySQL REPLACE INTO?

głosy
73

MySQL ma to niezwykle użyteczny jeszcze properitary REPLACE INTOpolecenia SQL.

Można to łatwo naśladowane w SQL Server 2005?

Rozpoczynanie nowej transakcji, robi Select(), a następnie albo UPDATEczy INSERT IGNORE i COMMITzawsze jest trochę uciążliwe, zwłaszcza gdy robi to we wniosku i dlatego zawsze mając 2 wersje instrukcji.

Zastanawiam się, czy nie jest łatwym i uniwersalnym sposobem realizacji takiej funkcji w SQL Server 2005?

Utwórz 01/08/2008 o 23:13
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
53

To jest coś, co denerwuje mnie o MSSQL ( rant na moim blogu ). Życzę MSSQL obsługiwane upsert.

Kod @ Dillie-O jest dobrym sposobem, w starszych wersjach SQL (+1 głos), ale nadal jest w zasadzie dwie operacje IO (the existsa następnie updatealbo insert)

Jest nieco lepszy sposób na to stanowisko , w zasadzie:

--try an update
update tablename 
set field1 = 'new value',
    field2 = 'different value',
    ...
where idfield = 7

--insert if failed
if @@rowcount = 0 and @@error = 0
    insert into tablename 
           ( idfield, field1, field2, ... )
    values ( 7, 'value one', 'another value', ... )

Zmniejsza to do jednej operacji IO, czy jest to zmiana, lub dwa jeśli wkładka.

MS Sql2008 wprowadza mergeod SQL: Standard 2003:

merge tablename as target
using (values ('new value', 'different value'))
    as source (field1, field2)
    on target.idfield = 7
when matched then
    update
    set field1 = source.field1,
        field2 = source.field2,
        ...
when not matched then
    insert ( idfield, field1, field2, ... )
    values ( 7,  source.field1, source.field2, ... )

Teraz to naprawdę tylko jedna operacja IO, ale kod straszne :-(

Odpowiedział 15/08/2008 o 13:50
źródło użytkownik

głosy
20

Funkcjonalność szukasz jest tradycyjnie nazywany upsert. Atleast wiedząc, co się nazywa może pomóc Ci znaleźć to, czego szukasz.

Nie sądzę, że SQL Server 2005 ma żadnych wielkich sposoby robienia tego. 2008 wprowadza sprawozdanie MERGE, które można wykorzystać do osiągnięcia tego celu, jak pokazano na: http://www.databasejournal.com/features/mssql/article.php/3739131 lub http://blogs.conchango.com/davidportas/archive/ 2007/11/14 / SQL-Server-2008-MERGE.aspx

Merge był dostępny w wersji beta 2005, ale usunięto go w ostatecznej wersji.

Odpowiedział 01/08/2008 o 23:22
źródło użytkownik

głosy
15

Co upsert / scalania robi coś do skutku ...

IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
   UPDATE [Table] SET...
ELSE
   INSERT IGNORE  INTO [Table]

Więc mam nadzieję, że kombinacja tych artykułów, a ten pseudo kod może dostać rzeczy ruchomych.

Odpowiedział 01/08/2008 o 23:31
źródło użytkownik

głosy
9

I napisał na blogu o tym problemie .

Najważniejsze jest to, że jeśli chcesz tanie aktualizacje ... i chcesz być bezpieczny dla jednoczesnego użytkowania. próbować:

update t
set hitCount = hitCount + 1
where pk = @id

if @@rowcount < 1 
begin 
   begin tran
      update t with (serializable)
      set hitCount = hitCount + 1
      where pk = @id
      if @@rowcount = 0
      begin
         insert t (pk, hitCount)
         values (@id,1)
      end
   commit tran
end

W ten sposób masz 1 operację aktualizacji i max 3 operacji dla wkładek. Tak więc, jeśli są ogólnie aktualizacją jest to bezpieczne tania opcja.

Byłbym bardzo ostrożny, aby nie używać niczego, co jest niebezpieczne dla jednoczesnego użytkowania. Jest naprawdę łatwo dostać kluczowych łamania podstawowych lub powielić wiersze w produkcji.

Odpowiedział 21/09/2008 o 23:05
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more