Si j'ai plusieurs instructions WHEN MATCHED dans une instruction MERGE, sont-elles toutes exécutées si elles sont vraies?
Mon exemple:
DECLARE @X bit = NULL;
--skipping the MERGE statement, straight to WHEN MATCHED
WHEN MATCHED AND A = 1
@X = 0;
WHEN MATCHED AND B = 1
@X = 1;
Quel est l'état de X dans chacune des 4 possibilités?
A|B|X
0|0|?
0|1|?
1|0|?
1|1|?
En gros, je suis curieux de savoir s’il existe une pause implicite après chaque clause WHEN MATCHED.
Pour répondre à votre question, oui, il n'y aura qu'un match, puis une pause. Toutefois, si vous souhaitez que la logique permette la mise en correspondance conditionnelle dans la mise à jour, l'instruction CASE
est plutôt utile pour cela.
Quelque chose comme ça à titre d'exemple:
MERGE INTO YourTable
USING (VALUES (1, 1, NULL), (0, 0, NULL), (0, 1, NULL), (1, 0, NULL))
T2 (a2,b2,c2)
ON a = a2 AND b = b2
WHEN MATCHED THEN
UPDATE SET c =
CASE
WHEN a = 1 THEN 0
WHEN b = 1 THEN 1
ELSE NULL
END
WHEN NOT MATCHED THEN
INSERT (a, b) VALUES (a2, b2);
SELECT * FROM YourTable ORDER BY a,b;
Et les résultats:
A B C
--------------
0 0 (null)
0 1 1
1 0 0
1 1 0
J'ai trouvé dans la documentation MSDN :
QUAND S'ADAPTE ALORS
Spécifie que toutes les lignes de target_table qui correspondent aux lignes renvoyées par ON et satisfont à toute condition de recherche supplémentaire sont mises à jour ou supprimées conformément à la clause.
L'instruction MERGE peut comporter au maximum deux clauses WHEN MATCHED. Si deux clauses sont spécifiées, la première clause doit être accompagnée d'une clause AND. Pour une ligne donnée, la seconde clause WHEN MATCHED n'est appliquée que si la première ne l'est pas. S'il existe deux clauses WHEN MATCHED, l'une doit spécifier une action UPDATE et l'autre, une action DELETE. Si UPDATE est spécifié dans la clause et que plusieurs lignes correspondent à une ligne de target_table, SQL Server renvoie une erreur. L'instruction MERGE ne peut pas mettre à jour la même ligne plus d'une fois, ni mettre à jour et supprimer la même ligne.
Il semble donc qu’une seule des instructions soit exécutée et qu’elles nécessitent un DELETE dans l’une et une UPDATE dans l’autre.
eh bien, la réponse est: voulez-vous vraiment le faire, car si vous le faisiez, vous changeriez une mise à jour basée sur un ensemble en agonisant comme une mise à jour lente comme dans un ensemble de lignes, vous ne sauriez vraiment pas quelles colonnes ont été modifiées enregistrement par enregistrement .
la question est donc de savoir si vous souhaitez obtenir des performances. Si tel est le cas, assurez-vous d’avoir des index couvrant la
WHEN MATCHED TARGET.FIELD1 = SOURCE:FIELD1 AND TARGET.FIELD2 = SOURCE:FIELD2 ...
sinon, vous devrez passer la souris sur vos mises à jour après la fusion en utilisant un déclencheur INSTEAD OF
...
Pas bon pour la vitesse, cependant, peut fonctionner si vous devez enregistrer qui a fait quoi ...
Code heureux
Walter