Aquí podría ser tu PUBLICIDAD


Implementación de SQL Server 2005 de MySQL REPLACE INTO?

votos
73

MySQL tiene este REPLACE INTOcomando SQL increíblemente útil pero apropiado .

¿Se puede emular esto fácilmente en SQL Server 2005?

Comenzar una nueva transacción, hacer una Select()y luego una UPDATEo INSERT IGNORE y COMMITsiempre es un poco molesto, especialmente cuando se hace en la aplicación y por lo tanto siempre manteniendo 2 versiones de la declaración.

Me pregunto si existe una manera fácil y universal de implementar dicha función en SQL Server 2005.

Publicado el 01/08/2008 a las 23:13
fuente por usuario Michael Stum
En otros idiomas...        العربية       

4 respuestas

votos
53

Esto es algo que me molesta acerca de MSSQL ( despotricar en mi blog ). Deseo que MSSQL sea compatible upsert.

El código de @Dillie-O es una buena forma en las versiones anteriores de SQL (+1 voto), pero aún así son básicamente dos operaciones IO (el existsy luego el updateo insert)

Hay una manera un poco mejor en esta publicación , básicamente:

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

Esto lo reduce a una operación IO si es una actualización, o dos si es una inserción.

MS Sql2008 presenta mergedesde el estándar 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, ... )

Ahora es realmente solo una operación IO, pero un código horrible :-(

Respondida el 15/08/2008 a las 01:50
fuente por usuario Keith


Aquí podría ser tu PUBLICIDAD


votos
20

La funcionalidad que está buscando se llama tradicionalmente UPSERT. Al menos saber cómo se llama puede ayudarlo a encontrar lo que está buscando.

No creo que SQL Server 2005 tenga ninguna buena manera de hacerlo. 2008 presenta la declaración MERGE que se puede usar para lograr esto como se muestra en: 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 estuvo disponible en la versión beta de 2005, pero lo eliminaron en la versión final.

Respondida el 01/08/2008 a las 11:22
fuente por usuario Karl Seguin

votos
15

Lo que el upsert / merge está haciendo es algo en el sentido de ...

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

Así que con suerte la combinación de esos artículos y este pseudo código pueden hacer que las cosas se muevan.

Respondida el 01/08/2008 a las 11:31
fuente por usuario Dillie-O

votos
9

Escribí una publicación en el blog sobre este tema .

La conclusión es que si quieres actualizaciones baratas ... y quieres estar seguro para el uso concurrente. tratar:

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

De esta forma tiene 1 operación para actualizaciones y un máximo de 3 operaciones para inserciones. Entonces, si generalmente está actualizando, esta es una opción segura y económica.

También sería muy cuidadoso de no utilizar nada que no sea seguro para el uso simultáneo. Es muy fácil obtener violaciones de clave primaria o filas duplicadas en producción.

Respondida el 21/09/2008 a las 11:05
fuente por usuario Sam Saffron