web-dev-qa-db-fra.com

Utiliser la clause Where avec la fusion

Dans la syntaxe ci-dessous avec le When Matched est-il possible de mettre à jour uniquement si la valeur dans la table de mise à jour diffère de la valeur dans la table des employés? Quelque chose de similaire à mon DDL ci-dessous - mais bien sûr, cela génère une erreur et ne fonctionne pas.

Que dois-je mettre à jour dans ma syntaxe pour ne mettre à jour que les lignes différentes? Ma mise à jour souhaitée serait de ne pas répéter chaque ligne qui correspond, mais uniquement de mettre à jour emp44 & emp55 car l'adresse est différente.

L'erreur présentée est

Msg 156, niveau 15, état 1, ligne 24
Syntaxe incorrecte près du mot clé "WHERE".

Syntaxe

  DECLARE @Emp Table (empid varchar(10), empaddress varchar(100))
  Insert Into @Emp Values 
  ('emp11', '111 No Blue'), 
  ('emp22', '222 No Blue'),
  ('emp33', '333 No Blue'), 
  ('emp44', '444 No Blue'),
  ('emp55', '555 No Blue');

Declare @EmpUpdates TABLE (empid varchar(10), empaddress varchar(100))
Insert Into @EmpUpdates Values
('emp11', '111 No Blue'), 
('emp22', '222 No Blue'),
('emp33', '333 No Blue'), 
('emp44', '999 No Blue'),
('emp55', '888 No Blue'),
('emp66', '4141 No Blue');

MERGE @Emp emp
Using @EmpUpdates eup
ON emp.empid = eup.empid
 WHEN MATCHED THEN
UPDATE
SET emp.empaddress = eup.empaddress
WHERE emp.empaddress <> eup.empaddress
WHEN NOT MATCHED BY TARGET THEN
INSERT (empid, empaddress)
VALUES(eup.empid, eup.empaddress)
7

Il n'y a pas de WHERE dans cette partie de l'instruction MERGE. Voir MERGE (Transact-SQL) dans la documentation pour l'aide sur la syntaxe.

Il y a une partie AND facultative dans WHEN MATCHED clause donc la réponse simple est de déplacer la condition ici:

MERGE @Emp emp
USING @EmpUpdates eup
ON emp.empid = eup.empid
WHEN MATCHED 
     AND emp.empaddress <> eup.empaddress
  THEN
    UPDATE
    SET emp.empaddress = eup.empaddress
WHEN NOT MATCHED BY TARGET 
  THEN 
    INSERT (empid, empaddress)
    VALUES (eup.empid, eup.empaddress) ;

Soyez prudent de gérer correctement les valeurs nulles (si empaddress est nullable).

Il est parfois plus explicite (et efficace) d'effectuer les opérations dans deux instructions distinctes (UPDATE et INSERT dans votre cas) dans une transaction.

Sachez également qu'il y a eu (et qu'il y a toujours) certains problèmes avec MERGE .

19
ypercubeᵀᴹ