Vă mulțumim pentru susținere

Implementarea SQL Server 2005 a MySQL REPLACE INTO?

MySQL are această comandă SQL REPLACE INTO , foarte folositoare și încă utilă.

Poate fi ușor de emulat în SQL Server 2005?

Începând cu o nouă tranzacție, efectuarea unui Select () și apoi UPDATE sau INSERT un pic de durere, mai ales atunci când o faci în aplicație și, prin urmare, păstrează întotdeauna 2 versiuni ale declarației.

Mă întreb dacă există o modalitate ușoară și universală de a implementa o astfel de funcție în SQL Server 2005?

0
adăugat editat

4 răspunsuri

Ceea ce face fuziunea / fuzionarea este ceva de genul ...

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

Deci, sperăm că combinarea acestor articole și acest cod pseudo poate face lucrurile în mișcare.

0
adăugat

Funcționalitatea pe care o căutați este denumită în mod tradițional un UPSERT. Atleast știind ce se numește ar putea să vă ajute să găsiți ceea ce căutați.

I don't think SQL Server 2005 has any great ways of doing this. 2008 introduces the MERGE statement that can be used to accomplish this as shown in: http://www.databasejournal.com/features/mssql/article.php/3739131 or http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge a fost disponibil în versiunea beta a anului 2005, dar au eliminat-o în versiunea finală.

0
adăugat

Am scris o postare pe blog despre această problemă .

Linia de jos este că dacă doriți actualizări ieftine ... și doriți să fiți în siguranță pentru utilizarea concomitentă. încerca:

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

În acest fel aveți o operație pentru actualizări și o operațiune de max. 3 pentru inserturi. deci, dacă actualizați în general, aceasta este o opțiune ieftină sigură.

De asemenea, aș fi foarte atent să nu folosesc nimic care nu este sigur pentru utilizarea concomitentă. Sale într-adevăr ușor pentru a obține încălcări cheie primară sau duplicat rânduri în producție.

0
adăugat

Acesta este un lucru care mă deranjează despre MSSQL ( hărțuit pe blogul meu ). Doresc ca MSSQL să fie acceptat upsert .

Codul lui Dillie-O este o metodă bună în versiunile mai vechi de SQL (+1 vot), dar încă mai există două operații IO ( există și apoi update code> insert )

Există un mod ușor mai bun pentru acest post , în esență:

--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', ... )

Acest lucru o reduce la o operațiune IO dacă este o actualizare sau două dacă o inserție.

MS Sql2008 introduce merge din standardul SQL: 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, ... )

Acum este chiar o singură operațiune IO, dar un cod îngrozitor :-(

0
adăugat
Mare, Mulțumesc! Salvează opțiunea Selectați și de multe ori nu are nevoie nici măcar de o teransacție în situațiile în care pot fi siguri că între actualizare și inserția "my" nu există altă inserție pentru acea cheie.
adăugat autor Michael Stum
@Michael Mai bine ai un indice unic pe acest tabel și manipularea erorilor cheie duplicate dacă intenționezi să folosești această soluție.
adăugat autor Sam Saffron
Da, după cum sa subliniat aici: weblogs.sqlteam.com/dang/archive/2009/01/31/… MERGE nu este atomic. Elimină o blocare de actualizare implicită, dar o eliberează înainte de a efectua o inserare, ceea ce provoacă o condiție de rasă care poate duce la încălcări ale cheii primare. Trebuie să utilizați un HOLDLOCK explicit în plus față de UPDLOCK implicit pentru ca operația să fie atomică. În prezent, nu este atomic, în ciuda faptului că pare a fi o singură d
adăugat autor Triynko
@Ceith Instrucțiunea dvs. de îmbinare nu funcționează. MERGE nu acceptă clauza WHERE , trebuie rescrisă folosind USING și ON . De asemenea, dacă nu adăugați WITH (HOLDLOCK) , s-ar putea întâmpla o cursă și un concurs INSERT s, unul dintre ele nereușind din cauza conflictului cheie.
adăugat autor Eugene Beresovsky
Sintaxa MERGE este greșită și este rezolvată într-un răspuns mai recent din partea aceluiași autor: stackoverflow.com/a/243670/24472</ a>
adăugat autor Larry
Interogarea de mai sus, urmată de o actualizare, poate fi încă nereușită. Cu o cheie unică puteți obține excepții cheie duplicate pe inserție. Vă recomandăm să adăugați la instrucțiunea de actualizare: tabelul UPDATE WITH (SERIALIZABLE) SET ...
adăugat autor Elan