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.
La documentation Salesforce décrit les trois modes en une phrase chacun. La colonne qui compte en production est la troisième.
| Mode | Ce qu'il fait | Ce qu'il ne fait jamais |
|---|---|---|
| Overwrite | Supprime toutes les lignes de la cible, puis écrit le résultat de la requête | Conserver quoi que ce soit, y compris quand la requête renvoie zéro ligne |
| Update | Met à jour les lignes dont la clé primaire existe déjà, ajoute les autres | Supprimer une ligne absente du résultat |
| Append | Ajoute le résultat à la fin de la cible | Mettre à jour une ligne existante |
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.
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.
| Mode | Doublon dans le résultat | Doublon avec une ligne déjà présente |
|---|---|---|
| Overwrite | Pas d'erreur, une seule ligne est gardée par clé | Sans objet, la cible a été vidée |
| Update | Erreur de contrainte de clé primaire | Mise à jour normale de la ligne existante |
| Append | Erreur de contrainte de clé primaire | Erreur de contrainte de clé primaire |
⚠️ 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
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.
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.
💡 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 →