← Retour aux Insights

Overwrite, Update, Append : les requêtes SQL qui réussissent en écrivant n'importe quoi

Pierre Frin Septembre 2026 7 min de lecture
une même requête, trois résultats dans la table cible Overwrite vide la table, puis écrit même à zéro ligne Update met à jour et ajoute ne supprime jamais Append ajoute à la suite jamais de mise à jour adhérent à jour, relancé tous les matins Marketing Cloud Engagement · Query Activity

Une mutuelle envoie chaque matin un rappel aux adhérents dont une cotisation arrive à échéance dans les sept jours. Une automation importe les échéances, une Query Activity alimente la data extension Cible_Relance, et un parcours Journey Builder démarre sur cette table. Le montage tourne depuis deux ans en mode Overwrite.

Au printemps, le marketing demande de garder la trace des adhérents relancés. Un développeur bascule l'activité en mode Update, sans toucher à la requête. Rien ne casse, la recette est bonne, les personnes sélectionnées sont les bonnes.

Trois semaines plus tard, le service client reçoit des appels d'adhérents parfaitement à jour qui reçoivent un rappel tous les matins. Le mode Update ajoute et met à jour, il ne supprime jamais. Les adhérents qui avaient payé restaient dans Cible_Relance avec leur ancienne échéance, et le parcours, qui relit la table à chaque exécution, les reprenait.

Trois modes, et trois choses qu'ils ne font jamais

La documentation Salesforce décrit les trois modes en une phrase chacun. La colonne qui compte en production est la troisième.

ModeCe qu'il faitCe qu'il ne fait jamais
OverwriteSupprime toutes les lignes de la cible, puis écrit le résultat de la requêteConserver quoi que ce soit, y compris quand la requête renvoie zéro ligne
UpdateMet à jour les lignes dont la clé primaire existe déjà, ajoute les autresSupprimer une ligne absente du résultat
AppendAjoute le résultat à la fin de la cibleMettre à jour une ligne existante

Choisir le mode selon la table

La règle de choix découle de l'usage de la table, pas de la requête. Une audience d'envoi ou une table de travail doit refléter l'état présent, donc Overwrite. Une table de référence enrichie par morceaux, où l'on veut garder des lignes que la requête du jour ne voit plus, relève d'Update. Append ne convient qu'aux journaux dont chaque ligne est nouvelle par construction, et encore : un Update sur une clé bien choisie fait la même chose tout en restant rejouable après un incident.

Retenons le point aveugle du modèle : aucun mode ne supprime de lignes sélectivement. Pour retirer des lignes d'une data extension, on réécrit la table entière en Overwrite.

La clé primaire décide, et elle ne prévient pas toujours

Le mode Update s'appuie sur la clé primaire de la cible pour trancher entre mise à jour et ajout. Sans clé primaire, il n'a aucun moyen de reconnaître une ligne existante. Le comportement face aux doublons diffère selon le mode, et c'est le mode le plus utilisé qui est le plus trompeur.

ModeDoublon dans le résultatDoublon avec une ligne déjà présente
OverwritePas d'erreur, une seule ligne est gardée par cléSans objet, la cible a été vidée
UpdateErreur de contrainte de clé primaireMise à jour normale de la ligne existante
AppendErreur de contrainte de clé primaireErreur de contrainte de clé primaire

Les doublons de clé en Overwrite

⚠️ En Overwrite, la ligne conservée n'est pas choisie par vous. Une requête qui produit des doublons de clé ne lève aucune erreur et écrit une valeur arbitraire : le prénom d'un autre titulaire, une échéance périmée. Décidez vous-même, avec un agrégat ou un classement, quelle ligne doit gagner.

Dans le cas de la mutuelle, un adhérent avec deux échéances dans la semaine produit deux lignes pour la même clé. Écrire la règle dans la requête coûte trois lignes de SQL et évite une valeur tirée au sort.

SELECT
    a.AdherentId,
    a.Email,
    LEFT(a.Prenom, 50)                    AS Prenom,
    MIN(e.DateEcheance)                   AS DateEcheance,
    CAST(SUM(e.Montant) AS DECIMAL(10,2)) AS Montant
FROM Echeances AS e
INNER JOIN Adherents AS a
    ON a.AdherentId = e.AdherentId
WHERE e.Statut = 'A_PAYER'
  AND e.DateEcheance >= CAST(GETDATE() AS DATE)
  AND e.DateEcheance <  DATEADD(DAY, 8, CAST(GETDATE() AS DATE))
  AND a.Email IS NOT NULL
GROUP BY a.AdherentId, a.Email, a.Prenom

Historiser les relances à part

Le montant devient le total dû sur la semaine, ce qu'il faut signaler à l'équipe qui rédige l'email. La demande de traçabilité, elle, se traite dans une seconde table : une activité lit Cible_Relance et écrit dans Historique_Relance en Update, avec une clé composée de l'identifiant et de la date d'échéance. Un adhérent relancé sept jours de suite pour la même échéance n'occupe qu'une ligne, et une relance manuelle après incident réécrit les mêmes clés au lieu de les dupliquer. La documentation signale au passage qu'une clé primaire ne doit pas dépasser 1 700 octets et que chaque clé supplémentaire ralentit les écritures : deux ou trois champs courts restent raisonnables.

Une colonne sans alias ne va nulle part

L'activité rapproche les colonnes du résultat et les champs de la cible par leur nom, et rien d'autre. Quatre contraintes en découlent.

Un champ de la cible absent de la requête reste vide, ou prend sa valeur par défaut s'il en a une. Pratique pour une date de chargement, dangereux pour un champ obligatoire. Le LEFT(a.Prenom, 50) de la requête précédente relève du même réflexe : une longueur de texte peut être augmentée sur une data extension, jamais réduite, alors autant tronquer explicitement à la source.

Ce que le moteur SQL accepte

💡 Le moteur n'accepte que des instructions SELECT. Jointures, UNION, sous-requêtes, GROUP BY et CASE passent. Variables, tables temporaires, expressions de table communes et procédures stockées sont exclues, et les commentaires ouverts par deux tirets figurent parmi les éléments non pris en charge : utilisez la forme fermée. Le dialecte est celui de SQL Server 2016, sans lui correspondre exactement.

Salesforce documente aussi un problème connu sur les décimaux : un champ Decimal utilisé dans une requête ne ressort pas forcément en décimal. Contrôlez les montants après la première exécution et convertissez explicitement, comme le fait le CAST ci-dessus.

Zéro ligne, statut terminé, envoi vide

Le mode Overwrite a un revers. Si le fichier du matin arrive vide, la requête renvoie zéro ligne, l'activité se termine sans erreur, et Cible_Relance est vidée. Personne n'est relancé, et aucune alerte ne part.

Contrôler le volume avec une Verification Activity

Automation Studio propose une Verification Activity, qui évalue une data extension selon des conditions que vous définissez, puis arrête l'automation, envoie une notification, ou les deux. On la place juste après la requête d'audience, avec une condition sur le nombre de lignes. Le plafond haut vaut autant que le plancher : une jointure devenue incorrecte multiplie les lignes sans lever d'erreur.

Pour garder une trace chiffrée, une petite requête en Update écrit le volume du jour dans une table de contrôle.

SELECT
    'Cible_Relance'                 AS NomTable,
    CAST(GETDATE() AS DATE)         AS DateControle,
    COUNT(*)                        AS NbLignes
FROM Cible_Relance

Avec NomTable et DateControle en clé primaire, la table accumule une ligne par jour, et une relance le même jour met simplement la ligne à jour. COUNT(*) renvoie toujours une ligne, même sur une table vide, et c'est précisément ce qui rend la trace fiable. Dernier point de vigilance sur la durée de vie du montage : Salesforce suspend une Query Activity après une erreur système ou 24 échecs consécutifs. Une requête cassée par un champ renommé finit par ne plus s'exécuter du tout, et la reprise consiste à corriger la cause puis à enregistrer l'activité de nouveau.

Si vous venez d'Adobe Campaign

Dans un workflow Adobe Campaign, l'activité de mise à jour de données sépare explicitement le type d'opération, insertion, mise à jour, insertion ou mise à jour, suppression, et les clés de réconciliation, que vous choisissez à chaque fois. Dans Marketing Cloud, la réconciliation repose toujours sur la clé primaire de la data extension cible, et aucun mode ne supprime de lignes.

Une requête Marketing Cloud mélange également deux rôles qu'Adobe Campaign distingue, la sélection et l'écriture. C'est pourquoi le mode d'écriture fait partie de la définition de l'activité et non de l'étape suivante, et pourquoi on peut le changer sans changer une ligne de SQL. C'est exactement ce qui est arrivé à la mutuelle.

Le réflexe à garder

Quand une table cible change de rôle, le mode d'écriture change avec elle. Avant de basculer une activité, posez une question simple : qu'est-ce qui doit disparaître de cette table quand la requête ne le renvoie plus ? Si la réponse est « tout ce qui n'est plus d'actualité », c'est Overwrite, et la traçabilité se met ailleurs.

Questions fréquentes

Quelle différence entre les modes Overwrite, Update et Append ?

Overwrite supprime toutes les lignes de la cible, puis écrit le résultat de la requête, y compris quand ce résultat est vide. Update met à jour les lignes dont la clé primaire existe déjà et ajoute les autres, mais ne supprime jamais une ligne absente du résultat. Append ajoute le résultat à la fin de la cible et ne met pas à jour une ligne existante. Le choix découle de l'usage de la table, pas de la requête.

Comment supprimer seulement certaines lignes d'une data extension ?

Aucun des trois modes ne supprime de lignes sélectivement : c'est le point aveugle du modèle d'écriture. Pour retirer des lignes d'une data extension, on réécrit la table entière en Overwrite avec une requête qui ne les renvoie plus. C'est pourquoi une audience d'envoi ou une table de travail, qui doit refléter l'état présent, reste en Overwrite.

Que se passe-t-il si ma requête produit des doublons de clé primaire ?

En Overwrite, aucune erreur n'est levée : une seule ligne est gardée par clé, et ce n'est pas vous qui la choisissez, donc la valeur écrite peut être le prénom d'un autre titulaire ou une échéance périmée. En Update comme en Append, un doublon à l'intérieur du résultat provoque une erreur de contrainte de clé primaire. La règle doit donc être écrite dans la requête, avec un agrégat ou un classement qui désigne la ligne gagnante.

Une requête qui renvoie zéro ligne fait-elle échouer l'automation ?

Non. En mode Overwrite, l'activité se termine sans erreur et la table cible est simplement vidée, donc personne n'est ciblé et aucune alerte ne part. Automation Studio propose une Verification Activity, qui évalue une data extension selon des conditions que vous définissez, puis arrête l'automation, envoie une notification, ou les deux. Le plafond haut vaut autant que le plancher, car une jointure devenue incorrecte multiplie les lignes sans lever d'erreur.

Pourquoi une colonne calculée n'arrive-t-elle pas dans la table cible ?

L'activité rapproche les colonnes du résultat et les champs de la cible par leur nom, et rien d'autre. Toute colonne calculée doit donc porter un alias égal au nom du champ cible, sinon elle n'a pas de nom et l'activité ne sait pas où l'écrire. Un champ de la cible absent de la requête reste vide, ou prend sa valeur par défaut s'il en a une, ce qui est pratique pour une date de chargement et dangereux pour un champ obligatoire.

Dans la même série
Pierre Frin
Fondateur Grokium · Consultant CRM · Certifié Adobe Campaign Classic et Salesforce Marketing Cloud Email Specialist

Vos automations écrivent-elles ce que vous croyez ?

Je peux relire vos Query Activities, vos modes d'écriture et vos contrôles de volume, et vous rendre un diagnostic écrit avec les corrections à appliquer.

Me décrire votre contexte →