Für zukünftige Studenten des Kurses "MS SQL Server Developer" wurde eine Übersetzung des Artikels vorbereitet.
Wir laden Sie außerdem ein, das offene Webinar zum Thema "Grafikdatenbanken in SQL Server" anzusehen . In dieser Lektion werden die Teilnehmer zusammen mit einem Experten untersuchen, was Diagrammdatenbanken sind und welche Optionen für die Arbeit mit Diagrammen und Hierarchien in SQL Server verfügbar sind.

Ich denke, jeder kennt bereits meine Meinung zu MERGE und warum ich mich davon fern halte . Aber hier ist ein weiteres Anti-Pattern, auf das ich ständig stoße, wenn UPSERT ausgeführt werden muss (UPdate inSERT - Aktualisieren Sie eine Zeile, falls vorhanden, und fügen Sie sie ein, wenn sie nicht vorhanden ist):
IF EXISTS (SELECT 1 FROM dbo.t WHERE [key] = @key)
BEGIN
UPDATE dbo.t SET val = @val WHERE [key] = @key;
END
ELSE
BEGIN
INSERT dbo.t([key], val) VALUES(@key, @val);
END
Es sieht ziemlich logisch aus und passt zu unserer Denkweise:
Gibt es eine Zeichenfolge für den angegebenen Schlüssel?
JA : Wir aktualisieren diese Zeile.
: .
, , , — . , (, , ). -, , :

, , , ( ):
UPDATE , ( "", "" " "). , . (Paul White) , (Martin Smith) .
, INSERT :
(deadlock) - ;
(key violation), ;
, .
— , . , XACT_ABORT , — , . , IF EXISTS ( ), . , , .
« ...»
(Dan Guzman) Conditional INSERT/UPDATE Race Condition, "UPSERT" Race Condition With MERGE.
(Michael Swart) Mythbusting: Concurrent Update/Insert Solutions, , , . MERGE Be Careful with the Merge Statement. .
, ( , ):
BEGIN TRANSACTION;
UPDATE dbo.t WITH (UPDLOCK, SERIALIZABLE) SET val = @val WHERE [key] = @key;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.t([key], val) VALUES(@key, @val);
END
COMMIT TRANSACTION;
? UPDLOCK ?
UPDLOCK ( , ).
SERIALIZABLE ( , ).
, 1000% . ( ) . , , , . , :

:
, , .
, «» . ( ), UPDATE.
, , - , «» .
, . , . , , .
, UPDATE ?
, UPDATE . , , INSERT, INSERT , UPDATE, UPSERT:
BEGIN TRANSACTION;
INSERT dbo.t([key], val)
SELECT @key, @val
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.t WITH (UPDLOCK, SERIALIZABLE)
WHERE [key] = @key
);
IF @@ROWCOUNT = 0
BEGIN
UPDATE dbo.t SET val = @val WHERE [key] = @key;
END
COMMIT TRANSACTION;
« », INSERT :
BEGIN TRANSACTION;
BEGIN TRY
INSERT dbo.t([key], val) VALUES(@key, @val);
END TRY
BEGIN CATCH
UPDATE dbo.t SET val = @val WHERE [key] = @key;
END CATCH
COMMIT TRANSACTION;
. / . .
?
INSERT / UPDATE, (Justin Pealing) , , , ?
- (TVP, Table-Valued Parameters), UPDATE JOIN, INSERT, NOT EXISTS. , :
CREATE PROCEDURE dbo.UpsertTheThings
@tvp dbo.TableType READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
UPDATE t WITH (UPDLOCK, SERIALIZABLE)
SET val = tvp.val
FROM dbo.t AS t
INNER JOIN @tvp AS tvp
ON t.[key] = tvp.[key];
INSERT dbo.t([key], val)
SELECT [key], val FROM @tvp AS tvp
WHERE NOT EXISTS (SELECT 1 FROM dbo.t WHERE [key] = tvp.[key]);
COMMIT TRANSACTION;
END
- , TVP (XML, - ..), JOIN . INSERT — UPDATE .
UPSERT- , , , , . , IF EXIST. (Paul White, sql.kiwi | @SQK_Kiwi) — .
MERGE (, - MERGE-), .
"MS SQL Server Developer".
« SQL Server».