SQL Server 2005 implementación de MySQL REEMPLAZAR EN?


MySQL tiene este comando SQL increíblemente útil pero propio REPLACE INTO.

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

Comenzar una nueva Transacción, hacer un Select() y luego UPDATE o INSERT y COMMIT siempre es un poco molesto, especialmente cuando lo hace en la aplicación y, por lo tanto, siempre mantiene 2 versiones de la declaración.

Me pregunto si hay una manera fácil y universal de implementar tal función en SQL Server 2005?

Author: Peter Featherstone, 2008-08-02

4 answers

Esto es algo que me molesta sobre MSSQL (despotricar en mi blog). Deseo MSSQL soportado upsert.

El código de @ Dillie-O es una buena manera en versiones SQL anteriores (+1 voto), pero sigue siendo básicamente dos operaciones IO (el exists y luego el update o insert)

Hay una manera un poco mejor en este post , 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 introduce merge de la SQL: 2003 estándar:

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 horrible código: - (

 55
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:56

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

No creo que SQL Server 2005 tenga grandes maneras de hacer esto. 2008 introduce la instrucció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 estaba disponible en la beta de 2005, pero lo eliminaron en la versión final.

 22
Author: Karl Seguin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-01 22:22:37

Lo que el upsert/merge está haciendo es algo al efecto de...

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

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

 16
Author: Dillie-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-01 22:31:36

Escribí una entrada de blog sobre este tema.

La conclusión es que si quieres actualizaciones baratas ... y desea estar seguro para el uso simultáneo. try:

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 manera tiene 1 operación para actualizaciones y un máximo de 3 operaciones para insertos. por lo tanto, si generalmente está actualizando esta es una opción segura y barata.

También tendría mucho cuidado de no usar nada que no sea seguro para el uso concurrente. Es muy fácil obtener violaciónes de clave primaria o filas duplicadas en producción.

 9
Author: Sam Saffron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-05 01:53:44