Estoy usando columnas rowversion para manejar la concurrencia optimista y quiero recuperar el nuevo valor rowversion cuando he hecho una actualización para que mi capa de datos tenga el último valor y puede realizar otra actualización obteniendo una excepción de concurrencia (a menos que otra persona haya actualizado el registro).Obteniendo el último valor rowversion/timestamp en la declaración de actualización - Servidor Sql
Estaba haciendo un get en la capa de datos después de hacer una actualización, pero esto no era muy eficiente o perfectamente confiable.
Para la siguiente tabla:
CREATE TABLE PurchaseType
(
PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
Name nvarchar(50) NOT NULL,
TS rowversion NOT NULL
)
me trataron:
CREATE PROCEDURE PurchaseType_UpdateWithGet
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT
AS
UPDATE PurchaseType
SET Name = @Name
WHERE PurchaseTypeCode = @PurchaseTypeCode
AND TS = @TS
SELECT @TS = TS FROM PurchaseType WHERE PurchaseTypeCode = @PurchaseTypeCode
GO
pero no fue del todo feliz debido a la posibilidad de no obtener el valor rowverion de actualización de otra persona. Entonces me encontré con la instrucción de salida en la documentación rowversion (http://msdn.microsoft.com/en-us/library/ms182776.aspx/http://msdn.microsoft.com/en-us/library/ms177564.aspx) y intentado esto:
CREATE PROCEDURE PurchaseType_UpdateWithOutput
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT
AS
DECLARE @Output TABLE (TS BINARY(8))
UPDATE PurchaseType
SET Name = @Name
OUTPUT inserted.TS into @Output
WHERE PurchaseTypeCode = @PurchaseTypeCode
AND TS = @TS
SELECT TOP 1 @TS = TS FROM @Output
GO
Esto funciona bien. En mis pruebas básicas (solo ejecutando 10000 llamadas y cronometrando), la opción de SALIDA tarda aproximadamente un 40% más pero aún menos de medio milisegundo. Ninguno tomó un tiempo medible con SET STATISTICS TIME ON.
Mi pregunta es, ¿alguien sabe de una manera mejor/más simple de hacer esto?
Tenía la esperanza de una función que podría usar similar a SCOPE_IDENTITY() para las columnas de identidad, pero no puedo encontrar algo así. Alguien sabe si me estoy perdiendo algo?
Gracias de antemano.
salida es el camino a seguir para recuperar cualquier valor generado en INSERT (y que incluye IDENTIDAD si me preguntas ...) –
OK, gracias por eso. ¿Algún motivo en particular por el cual prefieres OUTPUT a SCOPE_IDENTITY? –
Funciona con inserciones de varias filas –