J'ai un cas où l'utilisation du déclencheur à la place de l'insertion est nécessaire. Mes collègues et moi nous demandons lequel est le plus efficace (utilisation de la mémoire, temps de fonctionnement, etc.).Déclencheur actif MSSQL AU LIEU DE L'INSÉRER
Le déclencheur vérifie si l'enregistrement existe dans la table, si aucun n'insère la nouvelle ligne, sinon met à jour la ligne existante par sa clé. La clé primaire de cet exemple est la clé composite de (DocumentId, VatRate).
La première variante est de vérifier si le dossier existe déjà:
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;
La deuxième variante tente d'insérer et si insertion échoue une mise à jour suit:
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;
Note: Rollback à savepoint est requis, en raison de l'implémentation de TRY-CATCH lors de l'exécution de la transaction dans TSQL.
Lequel est le meilleur et pourquoi? Si vous avez une meilleure solution, s'il vous plaît partager.
jamais entendu parler de ([Merge] https://msdn.microsoft.com/en- us/library/bb510625.aspx)? insérera s'il n'existe pas et mettra à jour s'il existe. Pas besoin de toutes les vérifications. – xQbert
@xQbert Je suis aussi fan de 'MERGE' et je l'utilise encore mais je pense que cet article devrait être mis au courant. Je l'ai trouvé éducatif. https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ – scsimon
Comme d'autres l'ont dit, utilisez la fusion, mais n'utilisez certainement pas la deuxième variante - vous ne devriez pas utiliser la gestion des exceptions pour ce type de logique. Vous faites une supposition sur la raison pour laquelle vous êtes entré dans le bloc catch. –