Ich verwende Rowversion Spalten für die Behandlung optimistischer Nebenläufigkeit und möchte den neuen Zeilversion Wert zurück, wenn ich ein Update gemacht habe, so dass meine Datenschicht den neuesten Wert hat und kann ein weiteres Update mit dem Erhalt einer Parallelitätsausnahme durchführen (es sei denn, der Datensatz wurde von jemand anderem aktualisiert).Aktuellen Zeilversion/Timestamp-Wert in Update-Anweisung erhalten - Sql Server
Ich war gerade dabei, in die Datenschicht zu gelangen, nachdem ich ein Update gemacht hatte, aber das war nicht sehr effizient oder absolut zuverlässig.
Für die folgende Tabelle:
CREATE TABLE PurchaseType
(
PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
Name nvarchar(50) NOT NULL,
TS rowversion NOT NULL
)
Ich habe versucht:
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
war aber wegen der Möglichkeit, nicht immer den rowverion Wert von jemandem anderen Update nicht ganz zufrieden. Dann kam ich auf die OUTPUT-Anweisung in rowversion Dokumentation (http://msdn.microsoft.com/en-us/library/ms182776.aspx/http://msdn.microsoft.com/en-us/library/ms177564.aspx) und versucht, dies:
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
Das funktioniert gut. In meinen grundlegenden Tests (10000 Aufrufe und Timing) dauert die OUTPUT-Option etwa 40% länger, aber immer noch weniger als eine halbe Millisekunde. Bei SET STATISTICS TIME ON wurde keine messbare Zeit benötigt.
Meine Frage ist, kennt jemand eine bessere/einfachere Möglichkeit, dies zu tun?
Ich hatte auf eine Funktion gehofft, die ich ähnlich wie SCOPE_IDENTITY() für Identitätsspalten verwenden konnte, aber nichts dergleichen finden kann. Wer weiß, ob ich etwas verpasse?
Vielen Dank im Voraus.
Ausgang ist der Weg zu gehen jeden generierten Wert auf INSERT abgerufen werden (und das schließt IDENTITY wenn Sie mich fragen ...) –
OK, danke dafür. Gibt es einen besonderen Grund, warum Sie OUTPUT gegenüber SCOPE_IDENTITY bevorzugen? –
Es funktioniert mit mehrreihigen Einfügungen –