Vous êtes-vous déjà retrouvé à écrire des blocs IF BEGIN END ELSE BEGIN END longs et complexes dans SQL Server? Si c’est le cas, vous serez heureux de savoir qu’il existe un moyen plus efficace et concis de gérer ces scénarios – l’instruction MERGE.
L’instruction MERGE dans SQL Server vous permet d’effectuer plusieurs opérations (telles que INSERT, UPDATE et DELETE) dans une seule instruction, en fonction des résultats d’une jointure entre deux tables. Elle élimine la nécessité d’écrire des instructions séparées pour chaque opération, rendant votre code plus lisible et plus facile à maintenir.
Jetons un coup d’œil plus attentif à la structure et à la fonctionnalité de l’instruction MERGE à l’aide d’un exemple:
-- Préparer les tables de test
DECLARE @MyProducts TABLE (
ProductID INT PRIMARY KEY,
Name VARCHAR(40) NOT NULL,
Price MONEY NOT NULL,
[Description] VARCHAR(100) NOT NULL,
[LastModified] DateTime NOT NULL
);
DECLARE @ImportList TABLE (
TheProductID INT,
TheName VARCHAR(40),
LatestPrice MONEY,
Descr VARCHAR(100)
);
-- Charger les données d'exemple
INSERT INTO @MyProducts (ProductID, Name, Price, [Description], [LastModified])
VALUES
(35, 'WIDGET TYPE B', 99.95, 'Bleu', '12/5/1999'),
(44, 'WIDGET TYPE R', 88.95, 'Rouge', '12/8/2010'),
(59, 'WIDGET TYPE O', 112.95, 'Orange', '12/9/2010'),
(77, 'WIDGET TYPE G', 55.95, 'Vert', '12/15/2010'),
(110, 'WIDGET TYPE Y', 77.95, 'Jaune', '12/19/2010');
INSERT INTO @ImportList (TheProductID, TheName, LatestPrice, Descr)
VALUES
(44, 'Widget Type C', 78.95, 'Cramoisi'),
(111, 'Widget Type P', 94.95, 'Violet'),
(112, 'Widget Type M', 75.95, 'Mauve');
-- Afficher la table existante
SELECT 'AVANT' as [Label], * FROM @MyProducts;
-- Démontrer les données utilisées par la fusion
SELECT 'ExempleFullJoin' as [Label],
CASE
WHEN mp.ProductID IS NULL AND il.TheProductID IS NOT NULL THEN 'Non correspondant'
WHEN mp.ProductID IS NOT NULL AND il.TheProductID IS NULL THEN 'Non correspondant par la source'
WHEN mp.ProductID IS NOT NULL AND il.TheProductID IS NOT NULL THEN 'Correspondant'
END as [MergeAction],
mp.*,
il.*
FROM @MyProducts mp
FULL JOIN @ImportList il ON mp.ProductID = il.TheProductID;
-- Effectuer la fusion
MERGE INTO @MyProducts AS mp
USING (
SELECT TheProductID, UPPER(TheName) as [Name], LatestPrice, Descr
FROM @ImportList
) AS stg
ON mp.ProductID = stg.TheProductID
WHEN MATCHED THEN
UPDATE SET
mp.Name = stg.Name,
mp.Price = stg.LatestPrice,
mp.[Description] = stg.Descr,
mp.LastModified = CURRENT_TIMESTAMP
WHEN NOT MATCHED THEN
INSERT (ProductID, Name, Price, [Description], [LastModified])
VALUES (stg.TheProductID, stg.Name, stg.LatestPrice, stg.Descr, CURRENT_TIMESTAMP)
WHEN NOT MATCHED BY SOURCE AND (CURRENT_TIMESTAMP - mp.LastModified) > 3650 THEN
DELETE;
-- Afficher la table après la fusion
SELECT 'APRÈS' as [Label], * FROM @MyProducts;
Dans l’exemple ci-dessus, nous avons deux tables – @MyProducts
et @ImportList
. L’instruction MERGE
est utilisée pour fusionner les données de la table @ImportList
dans la table @MyProducts
en fonction d’une condition de jointure.
L’instruction MERGE
se compose de trois parties principales:
- MERGE INTO: Cette partie définit la table de destination où vous souhaitez mettre les données. Dans l’exemple, nous utilisons l’alias “mp” pour la table
@MyProducts
. - USING: Cette partie spécifie la source des nouvelles données. Dans notre exemple, nous utilisons une sous-requête pour sélectionner les colonnes requises de la table
@ImportList
et l’aliassons “stg” (abréviation de staging). - WHEN: Cette partie détermine l’action à prendre en fonction de la condition de jointure. Dans notre exemple, nous avons trois clauses
WHEN
:- WHEN MATCHED: Cette clause est exécutée lorsqu’une correspondance est trouvée entre les tables source et destination. Dans notre exemple, nous mettons à jour les lignes correspondantes dans la table
@MyProducts
avec les valeurs correspondantes de la table@ImportList
. - WHEN NOT MATCHED: Cette clause est exécutée lorsqu’une ligne existe dans la table source mais pas dans la table de destination. Dans notre exemple, nous insérons ces lignes dans la table
@MyProducts
. - WHEN NOT MATCHED BY SOURCE: Cette clause est exécutée lorsqu’une ligne existe dans la table de destination mais pas dans la table source. Dans notre exemple, nous supprimons ces lignes de la table
@MyProducts
si elles n’ont pas été modifiées depuis plus de 10 ans.
- WHEN MATCHED: Cette clause est exécutée lorsqu’une correspondance est trouvée entre les tables source et destination. Dans notre exemple, nous mettons à jour les lignes correspondantes dans la table
Il est important de noter que l’instruction MERGE
doit se terminer par un point-virgule.
L’instruction MERGE
est un outil puissant qui peut simplifier votre code et améliorer les performances en réduisant le nombre d’instructions séparées que vous devez écrire. Elle est particulièrement utile lorsqu’il s’agit de traiter de grands ensembles de données ou d’effectuer des transformations de données complexes.
Donc, la prochaine fois que vous vous retrouverez à écrire plusieurs blocs IF BEGIN END ELSE BEGIN END, envisagez d’utiliser l’instruction MERGE
pour rationaliser votre code et le rendre plus efficace.