Implementazione di SQL Server 2005 di MySQL REPLACE INTO?
-
08-06-2019 - |
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?
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.