Skip to main content

Manipulation des enregistrements avec le langage DML

Objectifs de formation

Une fois cette unité terminée, vous pourrez :

  • Utiliser DML pour insérer, mettre à jour et supprimer des enregistrements
  • Exécuter des instructions DML en masse
  • Utiliser la mise à jour/insertion pour insérer ou mettre à jour un enregistrement
  • Intercepter une exception DML
  • Utiliser une méthode Database pour insérer de nouveaux enregistrements avec l'option de succès partiel et traiter les résultats
  • Déterminer quand utiliser des instructions DML et des méthodes Database
  • Exécuter des opérations DML sur des enregistrements associés
Remarque

Remarque

Vous souhaitez apprendre en français ? Commencez le défi dans un Trailhead Playground en français et utilisez les traductions fournies entre crochets pour naviguer. Copiez et collez uniquement les valeurs en anglais, car les validations de défi reposent sur les données en anglais. Si vous ne réussissez pas le défi dans votre organisation en français, nous vous recommandons (1) de définir le paramètre régional sur les États-Unis, (2) de définir la langue sur l’anglais en suivant les instructions ici, puis (3) de cliquer à nouveau sur le bouton « Vérifier le défi ».

Consultez le badge Trailhead dans votre langue pour découvrir comment profiter de l’expérience Trailhead traduite.

Manipulation des enregistrements avec le langage DML

Le langage DML (Data Manipulation Language) vous permet de créer et de modifier des enregistrements dans Salesforce. DML offre une méthode claire qui permet de gérer les enregistrements à l'aide de simples instructions d'insertion, de mise à jour, de fusion, de suppression et de restauration d'enregistrements.

Apex est un langage orienté vers les données et enregistré sur Lightning Platform. Par conséquent, il a directement accès à vos données dans Salesforce. Contrairement aux autres langages de programmation qui nécessitent une configuration supplémentaire pour se connecter aux sources de données, le langage DML Apex facilite la gestion des enregistrements ! En appelant des instructions DML, vous pouvez exécuter rapidement des opérations sur vos enregistrements Salesforce. Cet exemple ajoute le compte Acme à Salesforce. Un sObject de compte est créé, puis transmis en tant qu’argument à l’instruction insert, qui conserve l’enregistrement dans Salesforce.

// Create the account sObject
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;

Instructions DML

Les instructions DML disponibles sont les suivantes :

  • insert
  • update
  • upsert
  • delete
  • undelete
  • merge

Chaque instruction DML accepte un sObject unique ou une liste (ou un tableau) de sObjects. L'utilisation d'une liste de sObjects est plus efficace pour traiter les enregistrements.

La plupart de ces instructions sont des opérations de base de données connues. Les instructions upsert et merge sont propres à Salesforce et peuvent se révéler très utiles.

L’opération DML upsert crée des enregistrements et met à jour des enregistrements sObject dans une instruction unique, à l’aide d’un champ défini pour déterminer la présence d’objets existants, ou du champ ID si aucun champ n’est spécifié.

L'instruction merge fusionne jusqu'à trois enregistrements du même type de sObject dans l'un des enregistrements, supprime les autres, et attribue un nouveau parent à tous les enregistrements associés.

Champ ID attribué automatiquement aux nouveaux enregistrements

Lors de l'insertion d'enregistrements, le système attribue un ID à chaque enregistrement. La valeur ID est conservée dans la base de données et automatiquement renseignée dans la variable sObject que vous avez utilisée comme argument dans l’appel DML.

L'exemple ci-dessous montre comment obtenir l'ID du sObject qui correspond au compte inséré.

// Create the account sObject
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;
// Get the new ID on the inserted sObject argument
ID acctID = acct.Id;
// Display this ID in the debug log
System.debug('ID = ' + acctID);
// Debug log result (the ID will be different in your case)
// DEBUG|ID = 001D000000JmKkeIAF







Remarque

Au-delà des concepts de base

La variable sObject de l'exemple contient l'ID après l'appel DML. Par conséquent, vous pouvez réutiliser cette variable sObject pour effectuer d'autres opérations DML, notamment des mises à jour, car le système peut mapper la variable sObject avec son enregistrement correspondant par la valeur ID.

Vous pouvez récupérer un enregistrement dans la base de données pour obtenir ses champs, y compris le champ ID, mais sans DML. Vous devez écrire une requête en utilisant le langage SOQL. Le langage SOQL est présenté dans une autre unité.

DML en masse

Vous pouvez effectuer des opérations DML sur un sObject unique ou en masse dans une liste de sObjects. L’option d’exécution en masse d’opérations DML est recommandée pour ne pas atteindre les limitations du gouverneur, notamment la limitation DML de 150 instructions par transaction Apex. Cette limitation garantit un accès équitable aux ressources partagées sur Lightning Platform. L'exécution d'une opération DML dans une liste de sObjects est prise en compte comme une seule instruction DML, pas une instruction pour chaque sObject individuel.

Cet exemple insère des contacts en masse en ajoutant la liste de contacts à un seul appel. L'exemple met ensuite à jour ces contacts en masse.

  1. Exécutez l'extrait ci-dessous dans la Developer Console à l'aide d'un Apex anonyme.
    // Create a list of contacts
    List<Contact> conList = new List<Contact> {
        new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
            new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
            new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
            new Contact(FirstName='Kim',LastName='Shain',Department='Education')};
    // Bulk insert all contacts with one DML call
    insert conList;
    // List to hold the new contacts to update
    List<Contact> listToUpdate = new List<Contact>();
    // Iterate through the list and add a title only
    //   if the department is Finance
    for(Contact con : conList) {
        if (con.Department == 'Finance') {
            con.Title = 'Financial analyst';
            // Add updated contact sObject to the list.
            listToUpdate.add(con);
        }
    }
    // Bulk update all contacts with one DML call
    update listToUpdate;
  2. Examinez les contacts récemment créés dans votre organisation.
    La fonction de deux contacts appartenant au service Finance doit être renseignée avec Financial analyst (Analyste financier).

Mise à jour/insertion d’enregistrements

Si vous avez une liste contenant aussi bien des enregistrements existants que nouveaux, vous pouvez traiter les insertions et les mises à jour de tous les enregistrements de la liste à l'aide de l'instruction upsert. La mise à jour/insertion évite la création d’enregistrements dupliqués. Il n’est pas nécessaire de déterminer au préalable quels sont les enregistrements existants, ce qui peut représenter un gain de temps.

L'instruction upsert mappe les sObjects avec les enregistrements existants en comparant les valeurs d'un champ. Si vous ne spécifiez aucun champ lors de l'appel de cette instruction, l'instruction upsert utilise l'ID du sObject pour mapper le sObject avec des enregistrements existants dans Salesforce. Vous pouvez également spécifier le champ de mappage à utiliser. Pour des objets personnalisés, spécifiez un champ personnalisé marqué comme ID externe. Pour des objets standard, vous pouvez spécifier n’importe quel champ dont la propriété idLookup est définie sur true. Par exemple, le champ Email (E-mail) de l’objet Contact ou User (Utilisateur) dispose d’une propriété idLookup définie. Pour vérifier la propriété d’un champ, reportez-vous à Référence d’objet pour Salesforce et la plate-forme Lightning.

Syntaxe de mise à jour/insertion

upsert sObject | sObject[]


upsert sObject | sObject[] field

Le champ facultatif est un jeton de champ. Par exemple, pour spécifier le champ MyExternalID, l'instruction est la suivante :

upsert sObjectList Account.Fields.MyExternalId;

La mise à jour/insertion utilise la clé primaire (ID) de l'enregistrement du sObject, un champ idLookup ou un champ ID externe afin de déterminer si un enregistrement doit être créé ou si un enregistrement existant doit être mis à jour :

  • Si la clé n'a aucune correspondance, un enregistrement d'objet est créé.
  • Si la clé a une correspondance, l'enregistrement d'objet existant est mis à jour.
  • Si la clé a plusieurs correspondances, une erreur est générée et l'enregistrement de l'objet n'est pas inséré ni mis à jour.

L'exemple ci-dessous montre comment l’opération de mise à jour/insertion met à jour un enregistrement de contact existant et insère un nouveau contact au cours d’un seul appel. Cet appel met à jour le contact existant Josh et insère le nouveau contact Kathy.

Remarque

Remarque

L'appel mappe le premier contact avec l'ID. La variable josh est réutilisée pour l'appel de mise à jour/insertion. L'ID de l'enregistrement a déjà été renseigné dans cette variable dans l'appel d'insertion précédent. Par conséquent, il n'est pas nécessaire de définir explicitement l'ID dans cet exemple.

  1. Exécutez l'extrait ci-dessous dans la fenêtre Execute Anonymous (Exécution anonyme) de la Developer Console.
    // Insert the Josh contact
    Contact josh = new Contact(FirstName='Josh',LastName='Kaplan',Department='Finance');
    insert josh;
    // Josh's record has been inserted
    //   so the variable josh has now an ID
    //   which will be used to match the records by upsert
    josh.Description = 'Josh\'s record has been updated by the upsert operation.';
    // Create the Kathy contact, but don't persist it in the database
    Contact kathy = new Contact(FirstName='Kathy',LastName='Brown',Department='Technology');
    // List to hold the new contacts to upsert
    List<Contact> contacts = new List<Contact> { josh, kathy };
    // Call upsert
    upsert contacts;
    // Result: Josh is updated and Kathy is created.
  2. Examinez tous les contacts de votre organisation.
    Votre organisation contient un seul enregistrement Josh Kaplan, pas deux, car l’opération de mise à jour/insertion a retrouvé l’enregistrement existant et l’a mis à jour, sans créer un enregistrement de contact. L'enregistrement de contact Kathy Brown existe également.

Vous pouvez également spécifier le champ à utiliser pour mettre en correspondance les enregistrements. Cet exemple utilise le champ Email (E-mail) sur Contact, car sa propriété idLookup est définie. L'exemple insère le contact Jane Smith, crée un deuxième sObject Contact (Contact), le renseigne avec la même adresse e-mail, puis appelle upsert pour mettre à jour le contact en utilisant le champ Email (E-mail) à des fins de mise en correspondance.

Remarque

Remarque

Si insert avait été utilisé dans cet exemple au lieu de upsert, un contact Jane Smith dupliqué aurait été inséré.

  1. Exécutez l'extrait ci-dessous dans la fenêtre Execute Anonymous (Exécution anonyme) de la Developer Console.
    Contact jane = new Contact(FirstName='Jane',
                             LastName='Smith',
                             Email='jane.smith@example.com',
                             Description='Contact of the day');
    insert jane;
    // 1. Upsert using an idLookup field
    // Create a second sObject variable.
    // This variable doesn’t have any ID set.
    Contact jane2 = new Contact(FirstName='Jane',
                             LastName='Smith',
                             Email='jane.smith@example.com',
                             Description='Prefers to be contacted by email.');
    // Upsert the contact by using the idLookup field for matching.
    upsert jane2 Contact.fields.Email;
    // Verify that the contact has been updated
    System.assertEquals('Prefers to be contacted by email.',
                       [SELECT Description FROM Contact WHERE Id=:jane.Id].Description);
  2. Examinez tous les contacts de votre organisation.
    Votre organisation contient un seul contact Jane Smith avec la description mise à jour.

Suppression d’enregistrements

Vous pouvez supprimer des enregistrements permanents à l'aide de l'instruction delete. Les enregistrements ne sont pas définitivement supprimés de la plate-forme Lightning, mais ils sont placés dans la corbeille pendant 15 jours, période pendant laquelle ils peuvent être restaurés.

L'exemple ci-dessous montre comment supprimer tous les contacts qui portent le nom Smith. Si vous avez exécuté l’exemple relatif au DML en masse, votre organisation doit contenir deux contacts Smith. Exécutez cet extrait de code dans la Developer Console à l'aide d'Apex anonyme, puis vérifiez qu'il n'existe plus aucun contact Smith.

Contact[] contactsDel = [SELECT Id FROM Contact WHERE LastName='Smith'];
delete contactsDel;
Remarque

Remarque

Cet extrait de code inclut une requête qui permet de récupérer les contacts (requête SOQL). Le langage SOQL est présenté dans une autre unité.

Exceptions d'instruction DML

Si une opération DML échoue, elle renvoie une exception de type DmlException. Vous pouvez saisir des exceptions dans votre code pour gérer les conditions d'erreur.

Cet exemple produit une DmlException, car il tente d'insérer un compte sans le champ obligatoire Name (Nom). L'exception est interceptée dans le bloc catch.

try {
    // This causes an exception because
    //   the required Name field is not provided.
    Account acct = new Account();
    // Insert the account
    insert acct;
} catch (DmlException e) {
    System.debug('A DML exception has occurred: ' +
                e.getMessage());
}



Méthodes Database

Apex contient la classe Database intégrée. Cette dernière fournit des méthodes qui exécutent des opérations DML et reproduisent les instructions DML équivalentes.

Les méthodes Database ci-dessous sont statiques et sont appelées dans le nom de la classe.

  • Database.insert()
  • Database.update()
  • Database.upsert()
  • Database.delete()
  • Database.undelete()
  • Database.merge()

Contrairement aux instructions DML, les méthodes Database ont un paramètre facultatif allOrNone qui permet de spécifier si l’opération doit être partiellement réussie. Lorsque ce paramètre est défini sur false, si des erreurs se produisent sur un ensemble partiel d'enregistrements, les enregistrements réussis sont acceptés et des erreurs sont renvoyées pour les enregistrements échoués. En outre, avec l'option de succès partiel, aucune exception n'est renvoyée.

Voici comment vous appelez la méthode insert avec le paramètre allOrNone défini sur false.

Database.insert(recordList, false);

Les méthodes Database renvoient des objets de résultat qui contiennent des informations sur la réussite ou l'échec de chaque enregistrement. Par exemple, les opérations d'insertion et de mise à jour renvoient chacune un tableau d'objets Database.SaveResult.

Database.SaveResult[] results = Database.insert(recordList, false);
Remarque

Remarque

L'opération de mise à jour/insertion renvoie des objets Database.UpsertResult et la suppression renvoie des objets Database.DeleteResult.

Par défaut, le paramètre allOrNone est défini sur true, ce qui signifie que la méthode Database se comporte comme son instruction DML équivalente et renvoie une exception en cas d’échec.

Les deux instructions suivantes sont équivalentes à l'instruction insert recordList;.

Database.insert(recordList);

Et :

Database.insert(recordList, true);







Remarque

Au-delà des concepts de base

En plus de ces méthodes, la classe Database contient des méthodes qui ne sont pas fournies en tant qu'instructions DML. Il s’agit par exemple des méthodes utilisées pour le contrôle et la restauration des transactions, des méthodes employées pour vider la corbeille, ainsi que des méthodes associées aux requêtes SOQL. Le langage SOQL est présenté dans une autre unité.

Exemple : insertion d’enregistrements avec l’option de succès partiel

Examinons un exemple de l'utilisation des méthodes Database. Cet exemple s’appuie sur celui relatif à DML en masse, mais remplace l'instruction DML par une méthode Database. La méthode Database.insert() est appelée avec l'option de succès partiel. Un contact de la liste n’a volontairement aucun champ, ce qui entraîne une erreur, car il ne peut pas être enregistré sans le champ obligatoire LastName. Trois contacts sont acceptés et le contact sans champ génère une erreur. La dernière partie de cet exemple reprend les résultats renvoyés et écrit des messages de débogage dans le journal de débogage.

  1. Exécutez cet exemple dans la fenêtre Execute Anonymous (Exécution anonyme) de la Developer Console.
    // Create a list of contacts
    List<Contact> conList = new List<Contact> {
            new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
            new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
            new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
            new Contact()};
    // Bulk insert all contacts with one DML call
    Database.SaveResult[] srList = Database.insert(conList, false);
    // Iterate through each returned result
    for (Database.SaveResult sr : srList) {
        if (sr.isSuccess()) {
            // Operation was successful, so get the ID of the record that was processed
            System.debug('Successfully inserted contact. Contact ID: ' + sr.getId());
        } else {
            // Operation failed, so get all errors
            for(Database.Error err : sr.getErrors()) {
                System.debug('The following error has occurred.');
                System.debug(err.getStatusCode() + ': ' + err.getMessage());
                System.debug('Contact fields that affected this error: ' + err.getFields());
    	 }
        }
    }
  2. Vérifiez les messages de débogage (utilisez le mot clé DEBUG pour le filtre).
    Un échec doit être consigné et trois contacts doivent être insérés.

Comparaison entre les instructions DML et les méthodes Database

  • Utilisez des instructions DML pour générer les erreurs rencontrées lors du traitement DML en masse sous la forme d’une exception Apex qui interrompt immédiatement le flux de contrôle (en utilisant des blocs try...catch). Ce comportement est semblable au traitement des exceptions dans la plupart des langages de procédure de base de données.
  • Utilisez des méthodes de classe Database pour autoriser le succès partiel d'une opération DML en masse. Si un enregistrement échoue, le reste de l'opération DML peut réussir. Votre application peut ensuite inspecter les enregistrements refusés et éventuellement retenter l'opération. Lors de l'utilisation de ce formulaire, vous pouvez écrire un code qui ne renvoie jamais d'erreur d'exception DML. À la place, votre code peut utiliser le tableau de résultats approprié pour déterminer la réussite ou l'échec. De la même façon que les instructions DML, les méthodes Database incluent une syntaxe qui prend en charge les exceptions renvoyées.

Créez et gérez des enregistrements associés à l'aide de relations.

Insertion d’enregistrements associés

Vous pouvez insérer des enregistrements associés à des enregistrements existants si une relation a été définie entre les deux objets, par exemple une relation de référence ou principal-détails. Un enregistrement est lié à un autre enregistrement par un ID de clé étrangère. Par exemple, en cas d'insertion d'un nouveau contact, vous pouvez spécifier l'enregistrement du compte associé du contact en définissant la valeur du champ AccountId.

Cet exemple montre comment ajouter un contact à un compte (l'enregistrement associé) en définissant le champ AccountId du contact. Le contact et le Account (compte) sont liés par une relation de référence.

  1. Exécutez l'extrait de code ci-dessous dans la fenêtre Anonymous Apex (Apex anonyme) de la Developer Console.
    Account acct = new Account(Name='SFDC Account');
    insert acct;
    // Once the account is inserted, the sObject will be
    // populated with an ID.
    // Get this ID.
    ID acctID = acct.ID;
    // Add a contact to this account.
    Contact mario = new Contact(
        FirstName='Mario',
        LastName='Ruiz',
        Phone='415.555.1212',
        AccountId=acctID);
    insert mario;
  2. Examinez les contacts de votre organisation.
    Un compte (SFDC Account [Compte SFDC]) a été créé et contient le contact Mario Ruiz dans la liste associée Contacts du compte.

Mise à jour d’enregistrements associés

Les champs d'enregistrements associés ne peuvent pas être mis à jour avec le même appel à l'opération DML et nécessitent un appel DML distinct. Par exemple, en cas d'insertion d'un nouveau contact, vous pouvez spécifier l'enregistrement du compte associé du contact en définissant la valeur du champ AccountId. Cependant, vous ne pouvez pas modifier le nom du compte sans mettre à jour le compte lui-même avec un appel DML distinct. De même, lors de la mise à jour d'un contact, si vous souhaitez également mettre à jour le compte associé du contact, vous devez émettre deux appels DML. L’exemple suivant met à jour un contact et le compte qui lui est associé à l’aide de deux instructions update.

// Query for the contact, which has been associated with an account.
Contact queriedContact = [SELECT Account.Name
                          FROM Contact
                          WHERE FirstName = 'Mario' AND LastName='Ruiz'
                          LIMIT 1];
// Update the contact's phone number
queriedContact.Phone = '(415)555-1213';
// Update the related account industry
queriedContact.Account.Industry = 'Technology';
// Make two separate calls
// 1. This call is to update the contact's phone.
update queriedContact;
// 2. This call is to update the related account's Industry field.
update queriedContact.Account;

Suppression d’enregistrements associés

L'opération delete prend en charge les suppressions en cascade. Si vous supprimez un objet parent, vous supprimez automatiquement ses enfants, si chaque enregistrement enfant peut être supprimé.

Par exemple, la suppression du compte que vous avez créé plus tôt (SFDC Account [Compte SFDC]) entraîne la suppression de son contact associé.

  1. Exécutez l'extrait de code ci-dessous dans la fenêtre Anonymous Apex (Apex anonyme) de la Developer Console.
    Account[] queriedAccounts = [SELECT Id FROM Account WHERE Name='SFDC Account'];
    delete queriedAccounts;
  2. Examinez les comptes et les contacts de votre organisation.
    Vous verrez que le compte et son contact associé ont été supprimés.

À propos des transactions

Les opérations DML sont exécutées dans une transaction. Toutes les opérations DML d'une transaction réussissent, ou bien la transaction entière est abandonnée et aucune donnée n'est transmise à la base de données si l'opération rencontre une erreur. La limite d'une transaction peut être un déclencheur, une méthode de classe, un bloc de code anonyme, une page Apex ou une méthode de service Web personnalisée. Par exemple, si un déclencheur ou une classe crée deux comptes et met à jour un contact, et si la mise à jour du contact échoue suite à l'échec d'une règle de validation, la transaction entière est abandonnée et aucun compte n'est conservé dans Salesforce.

Ressources

Partagez vos commentaires sur Trailhead dans l'aide Salesforce.

Nous aimerions connaître votre expérience avec Trailhead. Vous pouvez désormais accéder au nouveau formulaire de commentaires à tout moment depuis le site d'aide Salesforce.

En savoir plus Continuer à partager vos commentaires