usar two tables example como sql-server tsql insert-update

sql-server - example - sql merge two tables



T-SQL Insertar o actualizar (5)

Ambos funcionan bien, pero normalmente uso la opción 2 (pre-mssql 2008) ya que se lee un poco más claramente. Tampoco me preocuparía por el rendimiento aquí ... Si se convierte en un problema, puede usar NOLOCK en la cláusula exists . Aunque antes de comenzar a usar NOLOCK en todas partes, asegúrese de haber cubierto todas sus bases (índices y cosas de arquitectura de imagen grande). Si sabe que actualizará cada artículo más de una vez, entonces puede ser conveniente considerar la opción 1.

La opción 3 es no usar actualizaciones destructivas. Requiere más trabajo, pero básicamente inserta una nueva fila cada vez que cambian los datos (nunca actualice o elimine de la tabla) y tiene una vista que selecciona todas las filas más recientes. Es útil si desea que la tabla contenga un historial de todos sus estados anteriores, pero también puede ser una exageración.

Tengo una pregunta sobre el rendimiento de SQL Server.

Supongamos que tengo una tabla de persons con las siguientes columnas: id , name , surname .

Ahora, quiero insertar una nueva fila en esta tabla. La regla es la siguiente:

  1. Si id no está presente en la tabla, inserte la fila.

  2. Si la id está presente, entonces actualiza.

Tengo dos soluciones aquí:

Primero:

update persons set id=@p_id, name=@p_name, surname=@p_surname where id=@p_id if @@ROWCOUNT = 0 insert into persons(id, name, surname) values (@p_id, @p_name, @p_surname)

Segundo:

if exists (select id from persons where id = @p_id) update persons set id=@p_id, name=@p_name, surname=@p_surname where id=@p_id else insert into persons(id, name, surname) values (@p_id, @p_name, @p_surname)

¿Cuál es un mejor enfoque? Parece que en la segunda opción, para actualizar una fila, se debe buscar dos veces, mientras que en la primera opción, solo una vez. ¿Hay alguna otra solución al problema? Estoy utilizando MS SQL 2000.


Con el objetivo de ser un poco más seco, evito escribir la lista de valores dos veces.

begin tran insert into persons (id) select @p_id from persons where not exists (select * from persons where id = @p_id) update persons set name=@p_name, surname=@p_surname where id = @p_id commit

El name y el surname de la columna deben ser nulos.

La transacción significa que ningún otro usuario verá el registro "en blanco".

Edición: limpieza


La opción 1 parece buena. Sin embargo, si está en SQL Server 2008, también podría usar MERGE , que puede funcionar bien para tales tareas de UPSERT.

Tenga en cuenta que es posible que desee utilizar una transacción explícita y la opción XACT_ABORT para tales tareas, de modo que la consistencia de la transacción permanezca en el caso de un problema o cambio concurrente.


Puedes usar @@ RowCount para ver si la actualización hizo algo. Algo como:

UPDATE MyTable SET SomeData = ''Some Data'' WHERE ID = 1 IF @@ROWCOUNT = 0 BEGIN INSERT MyTable SELECT 1, ''Some Data'' END