Frage

MySQL hat dies unglaublich nützlich und dennoch eigenständig REPLACE INTO SQL-Befehl.

Kann dies problemlos in SQL Server 2005 emuliert werden?

Starten einer neuen Transaktion, Ausführen von a Select() und dann entweder UPDATE oder INSERT Und COMMIT ist immer etwas mühsam, besonders wenn man es in der Anwendung macht und man daher immer zwei Versionen der Aussage behält.

Ich frage mich, ob es ein einfaches und gibt Universal- Wie kann eine solche Funktion in SQL Server 2005 implementiert werden?

War es hilfreich?

Lösung

Das ist etwas, was mich an MSSQL nervt (schimpfe auf meinem Blog).Ich wünschte, MSSQL würde unterstützt upsert.

Der Code von @Dillie-O ist eine gute Möglichkeit in älteren SQL-Versionen (+1 Stimme), aber es handelt sich im Grunde immer noch um zwei E/A-Operationen (die exists und dann die update oder insert)

Es gibt einen etwas besseren Weg dieser Beitrag, grundsätzlich:

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

Dies reduziert es auf einen E/A-Vorgang, wenn es sich um ein Update handelt, oder auf zwei, wenn es sich um eine Einfügung handelt.

MS Sql2008 führt ein merge aus dem SQL:2003-Standard:

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

Jetzt ist es wirklich nur eine IO-Operation, aber schrecklicher Code :-(

Andere Tipps

Die gesuchte Funktionalität wird traditionell als UPSERT bezeichnet.Zumindest zu wissen, wie es heißt, könnte Ihnen helfen, das Gesuchte zu finden.

Ich glaube nicht, dass SQL Server 2005 dafür großartige Möglichkeiten bietet.2008 führt die MERGE-Anweisung ein, mit der dies erreicht werden kann, wie in: http://www.databasejournal.com/features/mssql/article.php/3739131 oder http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge war in der Beta von 2005 verfügbar, wurde jedoch in der endgültigen Version entfernt.

Was das Upsert/Merge bewirkt, hat die Wirkung von...

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

Hoffentlich kann die Kombination dieser Artikel und dieses Pseudocodes die Dinge in Bewegung bringen.

Ich habe ein geschrieben Blogbeitrag zu diesem Thema.

Das Fazit lautet: Wenn Sie günstige Updates wünschen ...und Sie möchten für die gleichzeitige Nutzung sicher sein.versuchen:

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

Auf diese Weise haben Sie 1 Vorgang für Aktualisierungen und maximal 3 Vorgänge für Einfügungen.Wenn Sie also generell aktualisieren, ist dies eine sichere und kostengünstige Option.

Ich würde auch sehr darauf achten, nichts zu verwenden, das für die gleichzeitige Verwendung unsicher ist.Es ist wirklich einfach, in der Produktion Primärschlüsselverletzungen oder doppelte Zeilen zu erkennen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top