MERGE Oracle SQL : Syntaxe, Exemples et Bonnes Pratiques

Apprenez la commande MERGE en Oracle SQL : syntaxe complète, exemples pratiques, erreurs courantes et bonnes pratiques pour vos bases de données.

Illustration du tutoriel SQL Oracle : MERGE Oracle SQL : Syntaxe, Exemples et Bonnes Pratiques

MERGE Oracle SQL : Fusionner des Données avec une Seule Instruction

La commande MERGE en Oracle SQL est l’une des instructions les plus puissantes du langage SQL. Elle permet d’insérer, mettre à jour ou supprimer des données dans une table cible en une seule opération atomique, en fonction d’une condition de correspondance avec une table source. Maîtriser le MERGE Oracle est essentiel pour tout développeur ou DBA travaillant sur des synchronisations de données en entreprise.

Publicité

Définition et utilisation du MERGE Oracle SQL

Le MERGE (parfois appelé UPSERT) est une instruction LMD (Langage de Manipulation des Données) introduite dans Oracle 9i. Elle combine en une seule requête les opérations INSERT, UPDATE et DELETE, selon qu’une ligne de la table source trouve ou non une correspondance dans la table cible.

Cas d’usage en entreprise

  • Synchronisation de référentiels : alimenter une table de production à partir d’une table de staging issue d’un ETL.
  • Chargement d’entrepôts de données (Data Warehouse) : mettre à jour les dimensions et les faits lors de chargements nocturnes.
  • Gestion des stocks : mettre à jour les quantités si un article existe, ou insérer une nouvelle ligne s’il est inconnu.
  • Réplication de données : maintenir deux tables synchronisées entre deux schémas ou deux bases de données Oracle.

L’avantage principal du MERGE est de réduire le nombre d’allers-retours vers la base de données et d’assurer la cohérence transactionnelle de l’opération.

Syntaxe complète du MERGE en Oracle SQL

MERGE INTO table_cible cible
USING table_source source
ON (condition_de_jointure)
WHEN MATCHED THEN
    UPDATE SET
        cible.colonne1 = source.colonne1,
        cible.colonne2 = source.colonne2
    [DELETE WHERE condition_suppression]
WHEN NOT MATCHED THEN
    INSERT (colonne1, colonne2, ...)
    VALUES (source.colonne1, source.colonne2, ...);

Explication des paramètres essentiels

ParamètreDescription
INTO table_cibleLa table qui sera modifiée (cible de la fusion).
USING table_sourceLa source de données : table, vue ou sous-requête.
ON (condition)La condition de correspondance entre la source et la cible (clé de jointure).
WHEN MATCHED THENBloc exécuté si une ligne correspondante est trouvée dans la cible.
WHEN NOT MATCHED THENBloc exécuté si aucune correspondance n’existe dans la cible.
DELETE WHEREOptionnel. Supprime les lignes correspondantes selon une condition supplémentaire.

Remarque Oracle : la clause USING accepte une sous-requête, ce qui offre une grande flexibilité pour filtrer ou transformer les données sources avant la fusion.

Publicité

Exemples pratiques de MERGE Oracle SQL

Exemple 1 – Synchronisation d’une table de clients

Contexte métier : Une entreprise reçoit chaque nuit un fichier de mise à jour de ses clients. Les nouvelles entrées doivent être insérées, et les clients existants (identifiés par leur CLIENT_ID) doivent être mis à jour.

-- Table cible : CLIENTS (table de production)
-- Table source : CLIENTS_STAGING (données chargées depuis le fichier)

MERGE INTO CLIENTS cible
USING CLIENTS_STAGING source
ON (cible.CLIENT_ID = source.CLIENT_ID)

WHEN MATCHED THEN
    -- Mise à jour des informations si le client existe déjà
    UPDATE SET
        cible.NOM          = source.NOM,
        cible.EMAIL        = source.EMAIL,
        cible.DATE_MAJ     = SYSDATE

WHEN NOT MATCHED THEN
    -- Insertion d'un nouveau client s'il n'existe pas encore
    INSERT (CLIENT_ID, NOM, EMAIL, DATE_CREATION)
    VALUES (source.CLIENT_ID, source.NOM, source.EMAIL, SYSDATE);

Après l’exécution, un COMMIT est recommandé pour valider la transaction :

COMMIT;

Exemple 2 – Gestion des stocks avec suppression conditionnelle

Contexte métier : Un système de gestion d’entrepôt doit synchroniser la table STOCK avec les données reçues d’un ERP. Si le stock d’un produit tombe à zéro après mise à jour, la ligne doit être supprimée.

-- Fusion avec clause DELETE conditionnelle (spécifique Oracle)
MERGE INTO STOCK cible
USING (
    -- Sous-requête comme source : filtrage des produits actifs uniquement
    SELECT PRODUIT_ID, QUANTITE, NOM_PRODUIT
    FROM STOCK_ERP
    WHERE STATUT = 'ACTIF'
) source
ON (cible.PRODUIT_ID = source.PRODUIT_ID)

WHEN MATCHED THEN
    UPDATE SET
        cible.QUANTITE    = source.QUANTITE,
        cible.NOM_PRODUIT = source.NOM_PRODUIT
    -- Suppression des lignes dont le stock est épuisé
    DELETE WHERE cible.QUANTITE = 0

WHEN NOT MATCHED THEN
    INSERT (PRODUIT_ID, NOM_PRODUIT, QUANTITE)
    VALUES (source.PRODUIT_ID, source.NOM_PRODUIT, source.QUANTITE);

COMMIT;

Point clé : la clause DELETE WHERE dans le bloc WHEN MATCHED est une fonctionnalité propre à Oracle SQL, absente dans d’autres SGBD comme PostgreSQL ou MySQL.

Erreurs courantes avec le MERGE Oracle et leurs solutions

Erreur ORA-30926 : impossible d’obtenir un ensemble stable de lignes dans les tables sources

Description : Cette erreur survient lorsque la condition ON du MERGE retourne plusieurs lignes sources correspondant à une même ligne cible. Oracle ne sait alors pas quelle valeur appliquer lors du UPDATE.

Exemple déclencheur :

-- Problème : CLIENT_ID = 101 apparaît deux fois dans CLIENTS_STAGING
-- Oracle ne peut pas décider quelle ligne utiliser pour le UPDATE
MERGE INTO CLIENTS cible
USING CLIENTS_STAGING source
ON (cible.CLIENT_ID = source.CLIENT_ID)
WHEN MATCHED THEN
    UPDATE SET cible.NOM = source.NOM;
-- >> ORA-30926 si CLIENT_ID = 101 existe en double dans CLIENTS_STAGING

Solution : Dédupliquer la source avec DISTINCT, GROUP BY ou la fonction analytique ROW_NUMBER() avant de l’utiliser dans le MERGE :

MERGE INTO CLIENTS cible
USING (
    -- On garde uniquement la dernière version de chaque client
    SELECT CLIENT_ID, NOM, EMAIL
    FROM (
        SELECT CLIENT_ID, NOM, EMAIL,
               ROW_NUMBER() OVER (PARTITION BY CLIENT_ID ORDER BY DATE_MAJ DESC) AS rn
        FROM CLIENTS_STAGING
    )
    WHERE rn = 1
) source
ON (cible.CLIENT_ID = source.CLIENT_ID)
WHEN MATCHED THEN
    UPDATE SET cible.NOM = source.NOM, cible.EMAIL = source.EMAIL
WHEN NOT MATCHED THEN
    INSERT (CLIENT_ID, NOM, EMAIL)
    VALUES (source.CLIENT_ID, source.NOM, source.EMAIL);

Résumé du MERGE Oracle SQL

Point cléDétail
RôleFusionner INSERT + UPDATE + DELETE en une seule instruction atomique
Disponibilité OracleDepuis Oracle 9i (DELETE WHERE depuis Oracle 10g)
Source de donnéesTable, vue ou sous-requête
Condition cléLa clause ON doit retourner une correspondance unique
Clause DELETE WHERESpécifique Oracle, dans le bloc WHEN MATCHED uniquement
Erreur fréquenteORA-30926 : doublons dans la source → dédupliquer avec ROW_NUMBER()
TransactionOpération DML : nécessite COMMIT ou ROLLBACK

2 bonnes pratiques Oracle pour le MERGE

  1. Toujours dédupliquer la source : avant d’utiliser une table ou une sous-requête dans la clause USING, assurez-vous que la clé de jointure est unique côté source. Utilisez ROW_NUMBER() ou GROUP BY pour garantir l’unicité et éviter l’erreur ORA-30926.
  2. Indexer la colonne de jointure : la colonne utilisée dans la clause ON de la table cible doit être indexée (idéalement une clé primaire ou un index unique). Cela améliore drastiquement les performances du MERGE sur de grands volumes de données.

Aller plus loin avec Oracle SQL

Pour approfondir vos connaissances sur les opérations de manipulation de données en Oracle SQL, voici trois sujets complémentaires qui vous aideront à maîtriser davantage cet environnement :

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité