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?
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ă.
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.
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 :-(
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.