Sto usando colonne rowversion per gestire la concorrenza ottimistica e voglio ottenere il nuovo valore di rowversion quando ho fatto un aggiornamento in modo che il mio livello dati abbia l'ultimo valore e può eseguire un altro aggiornamento ottenendo un'eccezione di concorrenza (a meno che il record non sia stato aggiornato da qualcun altro).Ottenere l'ultimo valore rowversion/timestamp nell'istruzione update - Sql Server
Stavo solo facendo un get nel livello dati dopo aver fatto un aggiornamento, ma questo non era molto efficiente o perfettamente affidabile.
Per la tabella seguente:
CREATE TABLE PurchaseType
(
PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
Name nvarchar(50) NOT NULL,
TS rowversion NOT NULL
)
ho provato:
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
ma non era del tutto felice a causa della possibilità di non ottenere il valore rowverion da aggiornamento di qualcun altro. Poi mi sono imbattuto la dichiarazione OUTPUT nella documentazione rowversion (http://msdn.microsoft.com/en-us/library/ms182776.aspx/http://msdn.microsoft.com/en-us/library/ms177564.aspx) e provato questo:
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
questo funziona bene. Nei miei test di base (solo eseguendo 10000 chiamate e cronometraggio) l'opzione OUTPUT impiega circa il 40% in più ma ancora meno di mezzo millisecondo. Nessuno dei due ha avuto tempo misurabile con SET STATISTICS TIME ON.
La mia domanda è, qualcuno sa di un modo migliore/più semplice per farlo?
Avevo sperato in una funzione che potrei usare simile a SCOPE_IDENTITY() per le colonne Identity ma non riesco a trovare nulla di simile. Qualcuno sa se mi manca qualcosa?
Grazie in anticipo.
OUTPUT è la strada da percorrere per recuperare qualsiasi valore generato su INSERT (e che comprende IDENTITÀ se mi chiedete ...) –
OK, grazie per questo. Qualche ragione particolare per cui preferisci OUTPUT rispetto a SCOPE_IDENTITY? –
Funziona con inserti multiriga –