DELTA et MERGE : deux granularités différentes
Un chargement DELTA par objet métier identifie les objets modifiés, retire leurs anciennes lignes du QVD et recharge leur état courant. Le MERGE intervient à une granularité plus fine : chaque ligne est accompagnée d’une opération d’insertion, de modification ou de suppression.
Cette précision ne rend pas le MERGE systématiquement plus performant. Elle évite de recharger toutes les lignes d’un objet lorsqu’une seule a changé, mais elle exige de produire des mouvements fiables. Le choix dépend du volume des données, de la fréquence des modifications et du coût de détection des écarts.
Le traitement est ici exécuté dans le cadre d’un rechargement normal de Qlik Sense. Cela ne signifie pas que l’intégralité de la table Oracle est relue chaque nuit : l’application charge le QVD déjà présent sur disque, puis récupère seulement les mouvements Oracle.
Comparer deux états pour identifier les changements
La détection repose sur deux états de LIGNES_FACTURE : le snapshot de référence N-1 et un nouvel état N. Chaque ligne est identifiée par ID_LIGNE_FACTURE, une clé unique et stable.
| Objet | Rôle |
|---|---|
LIGNES_FACTURE | Table métier Oracle |
LIGNES_FACTURE_SNAP_N_1 | État Oracle de référence (N-1) |
LF_SNAP_20261011_01 | Nouvelle version physique du snapshot |
LIGNES_FACTURE_MERGE | Table des mouvements du cycle courant |
Le nouvel état est matérialisé avant la comparaison : les requêtes travaillent sur deux ensembles cohérents. Les mouvements correspondent ainsi à une seule transition entre N-1 et N.
CREATE TABLE LF_SNAP_20261011_01 NOLOGGING AS
SELECT ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM LIGNES_FACTURE
WHERE ID_LIGNE_FACTURE IS NOT NULL;Le nom physique est propre à chaque exécution. Un index unique sur ID_LIGNE_FACTURE et des contrôles de volumétrie permettent de vérifier la qualité du snapshot avant de poursuivre. La référence LIGNES_FACTURE_SNAP_N_1 désigne toujours l’état précédent pendant cette étape. Dans cet exemple, elle est implémentée par une vue Oracle sur une table de snapshot physique.
Construire les mouvements INSERT, UPDATE et DELETE
La table LIGNES_FACTURE_MERGE est reconstruite chaque nuit à partir des écarts entre N-1 et N. Elle contient uniquement les mouvements du cycle courant : opération, ordre, clé métier et valeurs utiles aux insertions et modifications.
| TYPE_OPERATION | ID_DELTA | ID_LIGNE_FACTURE | Effet |
|---|---|---|---|
| I | 61001 | 1001 | Insertion d’une ligne |
| U | 61002 | 2044 | Modification d’une ligne |
| D | 61003 | 3098 | Suppression d’une ligne |
Les trois requêtes suivantes comparent le même état N matérialisé à la même référence N-1. La table de mouvements et la séquence Oracle existent déjà. Avant les insertions, on remet à zéro les mouvements du cycle précédent, uniquement lorsque le traitement précédent est terminé et que le processus de reprise l’autorise.
TRUNCATE TABLE LIGNES_FACTURE_MERGE;3.1 Insertion : la ligne apparaît dans N
INSERT INTO LIGNES_FACTURE_MERGE
(TYPE_OPERATION, ID_DELTA, ID_LIGNE_FACTURE,
PRODUIT, QUANTITE, CA_HT, MARGE)
SELECT 'I',
SEQ_LIGNES_FACTURE_MERGE.NEXTVAL,
n.ID_LIGNE_FACTURE,
n.PRODUIT, n.QUANTITE, n.CA_HT, n.MARGE
FROM LF_SNAP_20261011_01 n
WHERE NOT EXISTS (
SELECT 1
FROM LIGNES_FACTURE_SNAP_N_1 p
WHERE p.ID_LIGNE_FACTURE = n.ID_LIGNE_FACTURE
);3.2 Modification : la clé existe, mais les valeurs diffèrent
La comparaison porte sur les colonnes métier. L’opérateur INTERSECT permet ici de traiter correctement les valeurs nulles.
INSERT INTO LIGNES_FACTURE_MERGE
(TYPE_OPERATION, ID_DELTA, ID_LIGNE_FACTURE,
PRODUIT, QUANTITE, CA_HT, MARGE)
SELECT 'U',
SEQ_LIGNES_FACTURE_MERGE.NEXTVAL,
n.ID_LIGNE_FACTURE,
n.PRODUIT, n.QUANTITE, n.CA_HT, n.MARGE
FROM LF_SNAP_20261011_01 n
JOIN LIGNES_FACTURE_SNAP_N_1 p
ON p.ID_LIGNE_FACTURE = n.ID_LIGNE_FACTURE
WHERE NOT EXISTS (
SELECT n.PRODUIT, n.QUANTITE, n.CA_HT, n.MARGE FROM dual
INTERSECT
SELECT p.PRODUIT, p.QUANTITE, p.CA_HT, p.MARGE FROM dual
);3.3 Suppression : la ligne n’existe plus dans N
INSERT INTO LIGNES_FACTURE_MERGE
(TYPE_OPERATION, ID_DELTA, ID_LIGNE_FACTURE,
PRODUIT, QUANTITE, CA_HT, MARGE)
SELECT 'D',
SEQ_LIGNES_FACTURE_MERGE.NEXTVAL,
p.ID_LIGNE_FACTURE,
p.PRODUIT, p.QUANTITE, p.CA_HT, p.MARGE
FROM LIGNES_FACTURE_SNAP_N_1 p
WHERE NOT EXISTS (
SELECT 1
FROM LF_SNAP_20261011_01 n
WHERE n.ID_LIGNE_FACTURE = p.ID_LIGNE_FACTURE
);Après contrôle des mouvements, un COMMIT les rend disponibles pour Qlik. Cette table n’est pas un historique permanent : elle sera régénérée au prochain cycle Oracle.
En exploitation, il faut s’assurer que la génération Oracle est terminée avant le chargement Qlik. Si un cycle Qlik a échoué et que les mouvements correspondants ont déjà été remplacés par ceux du lendemain, une reconstruction complète est nécessaire : on ne peut pas reconstituer les mouvements manqués avec la seule table du jour.
Pourquoi utiliser ID_DELTA ?
Les mouvements du cycle sont identifiés et ordonnés par ID_DELTA. Ce champ permet à MERGE (ID_DELTA) de traiter les opérations dans leur ordre logique. Il ne constitue pas ici un curseur historique à mémoriser entre deux rechargements.
CREATE SEQUENCE SEQ_LIGNES_FACTURE_MERGE
START WITH 1
INCREMENT BY 1
NOCACHE;Une séquence Oracle attribue des identifiants distincts, mais ne garantit pas l’ordre de validation de transactions concurrentes. Le processus de génération doit être sérialisé. Dans cet exemple, les INSERT, puis UPDATE, puis DELETE sont produits successivement au sein d’un même cycle.
L’ordre physique des lignes renvoyées par le SELECT n’est pas la référence : c’est ID_DELTA qui détermine l’ordre logique du MERGE. Aucune variable vDernierDelta n’est requise.
Actualiser le snapshot sans perdre la référence précédente
Le nouveau snapshot et les mouvements sont d’abord préparés et contrôlés. La référence Oracle ne doit avancer qu’après le chargement Qlik, la publication et la validation du nouveau QVD. Sinon, un échec Qlik pourrait faire perdre la transition N-1 → N lors de la reprise. Une vue permet de conserver un nom stable pour les requêtes tout en pointant vers des tables physiques versionnées.
CREATE OR REPLACE VIEW LIGNES_FACTURE_SNAP_N_1 AS
SELECT ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM LF_SNAP_20261011_01;La commande remplace la définition de la vue sans supprimer l’ancien snapshot physique. Celui-ci reste disponible pour une restauration ou une vérification. L’utilisation de cette technique suppose que LIGNES_FACTURE_SNAP_N_1 ait été créée comme vue lors de l’initialisation.
La bascule et la génération des mouvements sont deux opérations distinctes : les instructions DDL Oracle entraînent des validations implicites. Le pilotage doit donc gérer la cohérence du lot et n’effectuer la bascule qu’après confirmation du succès du QVD. En cas d’échec, l’ancienne vue doit rester la référence pour la reprise. Une fois le snapshot avancé, le prochain calcul ne représente plus que les nouveaux écarts ; il ne faut pas supposer qu’un lot manqué reste récupérable dans la table de mouvements du lendemain.
Charger le QVD existant
Le premier chargement crée le QVD depuis la table complète Oracle. Lors des exécutions incrémentales suivantes, Qlik recharge le QVD publié en mémoire, avec un LOAD classique. Cette opération ne relit pas toute la table métier dans Oracle.
[LIGNES_FACTURE]:
LOAD
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM [lib://QVD_RAW/LIGNES_FACTURE.qvd] (qvd);Le QVD est la base sur laquelle seront appliqués les mouvements du cycle courant. Le premier chargement complet doit être cohérent avec le snapshot Oracle de référence.
Appliquer les mouvements avec MERGE
La syntaxe MERGE (ID_DELTA) applique les opérations à la table LIGNES_FACTURE, en utilisant la clé indiquée après ON. Le champ d’opération doit être le premier champ du flux chargé. Les valeurs Oracle I, U et D sont traduites en Insert, Update et Delete.
MERGE (ID_DELTA)
ON ID_LIGNE_FACTURE
CONCATENATE ([LIGNES_FACTURE])
LOAD
If(TYPE_OPERATION = 'I', 'Insert',
If(TYPE_OPERATION = 'U', 'Update',
If(TYPE_OPERATION = 'D', 'Delete', TYPE_OPERATION))) AS TYPE_OPERATION,
ID_DELTA,
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE;
SQL SELECT
TYPE_OPERATION,
ID_DELTA,
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM LIGNES_FACTURE_MERGE;CONCATENATE désigne la table à modifier, sans concaténer aveuglément les mouvements comme de nouvelles lignes. Les colonnes métier fournissent les valeurs des insertions et modifications ; la clé identifie les lignes à modifier ou supprimer. Le champ de séquence ID_DELTA peut être ajouté à la table résultante : si le QVD cible ne doit contenir que les champs métier, il faut le retirer après le MERGE et avant le STORE.
La table Oracle est recréée chaque nuit : aucun filtre sur un dernier numéro de mouvement traité n’est nécessaire. Les lignes de LIGNES_FACTURE_MERGE correspondent uniquement à la comparaison N-1/N du cycle.
Cycle Qlik : charger, fusionner, enregistrer
Le script incrémental est volontairement simple. Il charge le QVD précédent, applique les mouvements et réécrit le QVD complet. Le rechargement est normal du point de vue de Qlik, mais les données métier extraites d’Oracle sont limitées aux mouvements.
// 1. Recharger le QVD existant.
[LIGNES_FACTURE]:
LOAD
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM [lib://QVD_RAW/LIGNES_FACTURE.qvd] (qvd);
// 2. Appliquer les mouvements générés cette nuit par Oracle.
MERGE (ID_DELTA)
ON ID_LIGNE_FACTURE
CONCATENATE ([LIGNES_FACTURE])
LOAD
If(TYPE_OPERATION = 'I', 'Insert',
If(TYPE_OPERATION = 'U', 'Update',
If(TYPE_OPERATION = 'D', 'Delete', TYPE_OPERATION))) AS TYPE_OPERATION,
ID_DELTA,
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE;
SQL SELECT
TYPE_OPERATION,
ID_DELTA,
ID_LIGNE_FACTURE,
PRODUIT,
QUANTITE,
CA_HT,
MARGE
FROM LIGNES_FACTURE_MERGE;
// 3. Retirer le champ technique de séquence ajouté par MERGE.
DROP FIELD ID_DELTA FROM [LIGNES_FACTURE];
// 4. Publier le QVD actualisé.
STORE [LIGNES_FACTURE]
INTO [lib://QVD_RAW/LIGNES_FACTURE.qvd] (qvd);
DROP TABLE [LIGNES_FACTURE];Le STORE réécrit le QVD complet : le MERGE n’effectue pas une modification physique en place du fichier QVD. Dans cet exemple, DROP FIELD ID_DELTA évite de conserver le numéro de séquence dans le QVD métier. Dans une chaîne critique, il est prudent de préserver une copie exploitable du QVD précédent et de contrôler le résultat avant de considérer le cycle comme validé. La référence Oracle N-1 n’est avancée qu’après cette validation.
Dans un journal de rechargement, Qlik indique notamment les mouvements traités, par exemple Merge processed: 10 inserts, 4 updates, 2 deletes. Cette ligne confirme l’exécution du MERGE ; la concordance métier doit être vérifiée séparément.
Contrôles, reprise et rechargement complet
Après chaque chargement, le nombre de lignes du QVD est comparé au nombre de lignes Oracle attendu. En cas d’écart, un rechargement complet depuis Oracle permet de reconstruire le QVD sur une base saine. Un rechargement intégral périodique peut également être prévu pour repartir d’un état de référence fiable.
Le contrôle des volumes est utile, mais ne garantit pas à lui seul l’identité du contenu : une mise à jour incorrecte ou deux écarts qui se compensent peuvent laisser le même nombre de lignes. Selon les enjeux, on peut ajouter des contrôles de mesures, des empreintes par ligne ou des vérifications ciblées sur les clés modifiées.
Enfin, le STORE ne doit intervenir qu’après le succès du chargement des mouvements. Il faut éviter qu’une erreur de lecture Oracle laisse publier un QVD non actualisé comme si le cycle était terminé.
Pour approfondir, consulter la documentation Qlik sur MERGE et la documentation sur STORE.