Domanda

MySQL ha questo incredibilmente utile ma proprietario REPLACE INTO Comando SQL.

È possibile emularlo facilmente in SQL Server 2005?

Avviare una nuova transazione, eseguendo a Select() e poi neanche UPDATE O INSERT E COMMIT è sempre un po' fastidioso, soprattutto quando lo si fa nell'applicazione e quindi si mantengono sempre 2 versioni della dichiarazione.

Mi chiedo se esiste un modo facile e universale modo per implementare tale funzione in SQL Server 2005?

È stato utile?

Soluzione

Questo è qualcosa che mi infastidisce di MSSQL (sfogo sul mio blog).Vorrei che MSSQL fosse supportato upsert.

Il codice di @ Dillie-O è un buon modo nelle versioni SQL precedenti (+1 voto), ma sono comunque fondamentalmente due operazioni IO (il exists e poi il update O insert)

C'è un modo leggermente migliore di procedere questo post, fondamentalmente:

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

Ciò lo riduce a una operazione di I/O se si tratta di un aggiornamento o a due se si tratta di un inserimento.

MS Sql2008 introduce merge dallo standard 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, ... )

Ora è in realtà solo un'operazione IO, ma un codice orribile :-(

Altri suggerimenti

La funzionalità che stai cercando è tradizionalmente chiamata UPSERT.Almeno sapere come si chiama potrebbe aiutarti a trovare quello che stai cercando.

Non penso che SQL Server 2005 abbia ottimi modi per farlo.2008 introduce l'istruzione MERGE che può essere utilizzata per ottenere questo risultato, come mostrato in: http://www.databasejournal.com/features/mssql/article.php/3739131 O http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge era disponibile nella beta del 2005, ma è stato rimosso nella versione finale.

Ciò che sta facendo upsert/merge è qualcosa con l'effetto di...

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

Quindi si spera che la combinazione di questi articoli e questo pseudo codice possa far muovere le cose.

Ho scritto un post sul blog su questo problema.

La conclusione è che se vuoi aggiornamenti economici...e vuoi essere sicuro per l'utilizzo simultaneo.Tentativo:

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

In questo modo hai 1 operazione per gli aggiornamenti e un massimo di 3 operazioni per gli inserimenti.quindi, se stai generalmente aggiornando, questa è un'opzione sicura ed economica.

Farei anche molta attenzione a non utilizzare nulla che non sia sicuro per l'uso simultaneo.È davvero facile ottenere violazioni della chiave primaria o righe duplicate in produzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top