2016-11-22 2 views
0

Ich habe einen Fall, wenn die Verwendung von statt einfügen Trigger ist notwendig. Meine Kollegen und ich fragen mich, welcher ist effektiver (Speichernutzung, Zeit zu laufen, etc.).MSSQL effektiver Trigger INSTEAD OF INSERT

Der Trigger prüft, ob der Datensatz in der Tabelle existiert, wenn no die neue Zeile einfügt, ansonsten aktualisiert er die vorhandene Zeile mit seinem Schlüssel. Der Primärschlüssel in diesem Beispiel ist der zusammengesetzte Schlüssel von (DocumentId, VatRate).

Die erste Variante ist mit der Überprüfung, ob der Datensatz bereits vorhanden ist:

CREATE TRIGGER docvatsum_trg 
ON DocumentVatSummary 
INSTEAD OF INSERT 
AS 
BEGIN 
     IF EXISTS (
     SELECT 1 FROM DocumentVatSummary a 
     JOIN inserted b ON (a.DocumentId = b.DocumentId AND a.VatRate = b.VatRate) 
    ) 
     BEGIN 
     UPDATE DocumentVatSummary 
     SET 
      DocumentVatSummary.VatBase = i.VatBase, 
      DocumentVatSummary.VatTotal = i.VatTotal 
     FROM inserted i 
     WHERE 
      DocumentVatSummary.DocumentId = i.DocumentId AND 
      DocumentVatSummary.VatRate = i.VatRate 
     END 
     ELSE 
     BEGIN 
     INSERT INTO DocumentVatSummary 
     SELECT * FROM inserted 
     END 
END; 

Die zweite Variante einzufügen versucht und wenn Einsatz nicht ein Update folgt:

CREATE TRIGGER docvatsum_trg 
ON DocumentVatSummary 
INSTEAD OF INSERT 
AS 
BEGIN 
    SAVE TRANSACTION savepoint 
    BEGIN TRY 
     INSERT INTO DocumentVatSummary 
     SELECT * FROM inserted 
    END TRY 
    BEGIN CATCH 
     IF XACT_STATE() = 1 
     BEGIN 
      ROLLBACK TRAN savepoint 

      UPDATE DocumentVatSummary 
      SET 
       DocumentVatSummary.VatBase = i.VatBase, 
       DocumentVatSummary.VatTotal = i.VatTotal 
      FROM inserted i 
      WHERE 
       DocumentVatSummary.DocumentId = i.DocumentId AND 
       DocumentVatSummary.VatRate = i.VatRate 
     END 
    END CATCH 
END; 

Hinweis: Rollback zu Sicherungspunkt ist erforderlich, aufgrund der TRY-CATCH-Implementierung in laufenden Transaktionen in TSQL.

Welcher ist besser und warum? Wenn Sie eine bessere Lösung haben, teilen Sie bitte.

+3

jemals hören von [MERGE] (https://msdn.microsoft.com/en- us/Bibliothek/bb510625.aspx)? Wird eingefügt, wenn nicht existiert, und aktualisieren, falls vorhanden. Keine Notwendigkeit für die Überprüfung. – xQbert

+0

@xQbert Ich bin auch ein Fan von 'MERGE' und benutze es immer noch, aber ich denke dieser Artikel sollte darauf aufmerksam gemacht werden. Ich fand es lehrreich. https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ – scsimon

+0

Wie andere gesagt haben, verwenden Sie Merge, aber verwenden Sie definitiv nicht die zweite Variante - Sie sollten nicht Verwenden Sie die Ausnahmebehandlung für diese Art von Logik. Sie machen eine Vermutung darüber, warum Sie den Catch-Block betreten haben. –

Antwort

1

Verwendung in Ihrem Trigger MERGE wie hier erklärt:

MERGE SYNTAX

Codebeispiel:

DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20)); 

MERGE INTO Sales.SalesReason AS Target 
USING (VALUES ('Recommendation','Other'), 
       ('Review', 'Marketing'), 
       ('Internet', 'Promotion')) 
     AS Source (NewName, NewReasonType) 
ON Target.Name = Source.NewName 
WHEN MATCHED THEN 
UPDATE SET ReasonType = Source.NewReasonType 
WHEN NOT MATCHED BY TARGET THEN 
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) 
OUTPUT $action INTO @SummaryOfChanges; 
Verwandte Themen