Skip to main content

Manipular registros com DML

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:

  • Usar a DML para inserir, atualizar e excluir registros.
  • Executar instruções DML em massa.
  • Usar o upsert para inserir ou atualizar um registro.
  • Capturar uma exceção de DML.
  • Usar um método Database para inserir novos registros com a opção de sucesso parcial e processar os resultados.
  • Saber quando usar instruções DML e quando usar métodos Database.
  • Executar operações de DML em registros relacionados.
Nota

Nota

Deseja aprender em português (Brasil)? Comece o desafio em um Trailhead Playground de português (Brasil) e use as traduções fornecidas entre parênteses para navegar. Copie e cole somente os valores em inglês porque as validações dos desafios dependem de dados em inglês. Se você não passar no desafio em sua organização de português (Brasil), recomendamos que (1) mude o local para os Estados Unidos, (2) mude o idioma para inglês, seguindo as instruções aqui, e (3) clique novamente no botão “Validar o desafio”.

Consulte o emblema Trailhead no seu idioma para saber mais sobre como aproveitar a experiência de Trailhead em outros idiomas.

Manipular registros com DML

Crie e modifique registros no Salesforce usando a Data Manipulation Language (Linguagem de manipulação de dados), abreviada como DML. A DML proporciona uma maneira simples de gerenciar registros, fornecendo instruções simples para inserir, atualizar, mesclar, excluir e restaurar registros.

Como Apex é uma linguagem centrada em dados e salva na Lightning Platform, ela tem acesso direto aos seus dados no Salesforce. Ao contrário de outras linguagens de programação que exigem configuração extra para se conectar a fontes de dados, com a DML do Apex é fácil gerenciar registros! Chamando as instruções DML, você pode executar rapidamente operações em seus registros do Salesforce. Neste exemplo a conta Acme é adicionada ao Salesforce. Primeiramente, cria-se um sObject da conta e, em seguida, ele é aprovado como um argumento para a instrução inserir, que persiste o registro no 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;

Demonstrativos DML

As seguintes instruções DML estão disponíveis.

  • insert (inserir)
  • update (atualizar)
  • upsert (inserir e atualizar)
  • delete (excluir)
  • undelete (desfazer exclusão)
  • merge (mesclar)

Cada instrução DML aceita um único sObject ou uma lista (ou matriz) de sObjects. Operar em uma lista de sObjects é uma maneira mais eficiente de processar registros.

Todas essas instruções, exceto duas, são operações de banco de dados familiares. As instruções upsert e merge são específicas do Salesforce e podem ser bastante úteis.

A operação DML upsert (inserir e atualizar) cria novos registros e atualiza os registros sObject em uma única instrução, usando um campo especificado para determinar a presença de objetos existentes ou o campo de ID caso nenhum campo seja especificado.

A instrução merge mescla até três registros do mesmo tipo de sObject em um dos registros, excluindo os demais e reassociando quaisquer registros relacionados.

Campo ID autoatribuído a novos registros

Ao inserir registros, o sistema atribui uma ID a cada um deles. Além de persistir o valor ID no banco de dados, o valor ID também é preenchido automaticamente na variável sObject que você usou como argumento na chamada DML.

Este exemplo mostra como obter a ID do sObject que corresponde à conta inserida.

// 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







Observação

Ir além das noções básicas

Como a variável sObject no exemplo contém a ID após a chamada DML, é possível reutilizar esta variável sObject para realizar outras operações DML – como atualizações – pois o sistema conseguirá mapear a variável sObject ao seu registro correspondente combinando a ID.

É possível recuperar um registro do banco de dados para obter seus campos, incluindo o campo ID, mas isso não pode ser feito com a DML. Será preciso escrever uma consulta usando SOQL. Você aprenderá sobre a SOQL em outra unidade.

DML em massa

É possível executar operações DML em um único sObject ou em massa, em uma lista de sObjects. Realizar operações DML em massa é a maneira recomendada, porque ajuda a evitar atingir os limites de administrador, tais como o limite DML de 150 instruções por transação do Apex. Esse limite está em vigor para garantir um acesso justo aos recursos compartilhados na Lightning Platform. Executar uma operação DML em uma lista de sObjects conta como uma instrução DML, não como uma instrução para cada sObject.

Este exemplo insere contatos em massa por meio da inserção de uma lista de contatos em uma chamada. Então, a amostra também atualiza esses contatos em massa.

  1. Execute este trecho de código no Developer Console usando o Apex anônimo.
    // 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. Inspecione os contatos recém-criados em sua organização.
    Dois dos contatos que estão no departamento financeiro devem ter seus títulos preenchidos com Financial analyst (Analista financeiro).

Inserir e atualizar registros

Se você tem uma lista que contém uma mistura de registros novos e existentes, pode processar inserções e atualizações de todos os registros da lista usando a instrução upsert. Essa instrução ajuda a evitar a criação de registros duplicados e pode ajudá-lo a ganhar tempo, já que você não tem que determinar quais registros foram criados primeiro.

A instrução upsert coincide com os sObjects com registros existentes, comparando os valores de um campo. Se você não especificar um campo ao chamar esta instrução, a instrução upsert usa a ID do sObject para coincidir o sObject com os registros existentes no Salesforce. Você também pode especificar um campo para usar como correspondência. Para objetos personalizados, especifique um campo personalizado marcado como ID externa. Para objetos padrão, você pode especificar qualquer campo que tenha a propriedade idLookup definida como verdadeira. Por exemplo, o campo Email de Contato ou Usuário tem a propriedade idLookup definida. Para verificar a propriedade de um campo, consulte Referência de objeto para Salesforce e Lightning Platform.

Sintaxe de inserir e atualizar

upsert sObject | sObject[]


upsert sObject | sObject[] field

O campo opcional é um token de campo. Por exemplo, para especificar o campo MyExternalID, a instrução é:

upsert sObjectList Account.Fields.MyExternalId;

A instrução inserir e atualizar usa a chave primária do registro sObject (a ID), um campo idLookup ou um campo de ID externa para determinar se deve criar um novo registro ou atualizar um registro existente:

  • Se a chave não for correspondida, um novo registro de objeto é criado.
  • Se a chave for correspondida uma vez, o registro de objeto existente é atualizado.
  • Se a chave for correspondida várias vezes, um erro é gerado e o registro de objeto não é inserido nem atualizado.

Este exemplo mostra como a instrução "inserir e atualizar" atualiza um registro de contato existente e insere um novo contato em uma chamada. Esta chamada de inserção e atualização atualiza o contato Josh existente e insere um novo contato: Kathy.

Nota

Nota

A chamada de inserção e atualização usa a ID para corresponder o primeiro contato. A variável josh está sendo reutilizada para a chamada de inserção e atualização. Esta variável já foi preenchida com a ID de registro da chamada de inserção anterior, de modo que a ID não precisa ser definida explicitamente neste exemplo.

  1. Execute este trecho de código na janela Executar anônimo do 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. Inspecione todos os contatos da sua organização.
    Sua organização terá apenas um registro Josh Kaplan e não dois, porque a operação de inserção e atualização encontrou o registro existente e o atualizou em vez de criar um novo registro de contato. Um registro de contato Kathy Brown também estará lá.

Você também pode especificar um campo a ser usado para registros correspondentes. Esse exemplo usa o campo Email no Contato porque tem a propriedade idLookup definida. O exemplo insere o contato Jane Smith e cria um segundo contato sObject. Em seguida, preenche-o com o mesmo email e, finalmente, efetua a chamada upsert para atualizar o contato usando o campo de email para correspondência.

Observação

Nota

Se insert fosse usado neste exemplo em vez de upsert, um contato duplicado Jane Smith seria inserido.

  1. Execute este trecho de código na janela Executar anônimo do 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. Inspecione todos os contatos da sua organização.
    Sua organização terá apenas um contato Jane Smith com a descrição atualizada.

Excluir registros

Você pode excluir registros persistentes usando a instrução delete. Os registros excluídos não são excluídos permanentemente da Lightning Platform, mas são colocados na Lixeira por 15 dias, de onde podem ser restaurados.

Este exemplo mostra como excluir todos os contatos com sobrenome Smith. Se você executar o exemplo para a DML em massa, sua organização já deverá ter dois contatos com o sobrenome Smith. Execute este trecho de código no Developer Console usando o Apex anônimo e, em seguida, verifique se já não há contatos com o sobrenome Smith.

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

Nota

Este trecho de código inclui uma consulta para recuperar os contatos (uma consulta SOQL). Você aprenderá mais sobre a SOQL em outra unidade.

Exceções da instrução DML

Se uma operação DML falha, ela retorna uma exceção do tipo DmlException. Você pode capturar exceções em seu código para lidar com situações de erro.

Este exemplo produz uma DmlException por tentar inserir uma conta sem o campo de Nome obrigatório. A exceção é detectada no bloco 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étodos Database

O Apex contém a classe Database integrada, que fornece métodos que executam operações DML e espelham as instruções DML equivalentes.

Os métodos Database são estáticos e chamados no nome da classe.

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

Diferentemente de instruções DML, métodos Database têm um parâmetro allOrNone opcional que permite que você especifique se a operação pode ser parcialmente bem-sucedida. Quando esse parâmetro está definido como false, caso ocorram erros em um conjunto parcial de registros, os registros bem-sucedidos serão confirmados e os erros serão retornados para os registros de falha. Além disso, com a opção de sucesso parcial, nenhuma exceção é gerada.

Você chama o método insert (inserir) com o parâmetro allOrNone definido como false da seguinte forma.

Database.insert(recordList, false);

Os métodos Database retornam objetos de resultado contendo informações de sucesso ou falha para cada registro. Por exemplo, cada operação de inserir e atualizar retorna uma matriz de objetos Database.SaveResult.

Database.SaveResult[] results = Database.insert(recordList, false);
Observação

Nota

A operação upsert (inserir e atualizar) retorna objetos Database.UpsertResult e a operação de excluir retorna objetos Database.DeleteResult.

Por padrão, o parâmetro allOrNone é definido como true, o que significa que o método Database se comporta como sua instrução DML equivalente e gera uma exceção se uma falha é encontrada.

As duas instruções a seguir são equivalentes à instrução insert recordList;.

Database.insert(recordList);

E:

Database.insert(recordList, true);







Observação

Ir além das noções básicas

Além desses métodos, a classe Database contém métodos que não são fornecidos como instruções DML. Por exemplo, métodos usados para controle e reversão de transação, para esvaziar a Lixeira, e métodos relacionados a consultas SOQL. Você aprenderá sobre a SOQL em outra unidade.

Exemplo: Inserir registros com sucesso parcial

Vamos examinar um exemplo que utiliza os métodos Database. Este exemplo se baseia no exemplo do DML em massa, mas substitui a instrução DML por um método Database. O método Database.insert() é chamado com a opção de sucesso parcial. Um contato na lista não tem campos intencionalmente e causará um erro, pois o contato não pode ser salvo sem o campo obrigatório LastName. Três contatos são confirmados e o contato sem campos gera um erro. A última parte deste exemplo itera nos resultados retornados e escreve mensagens de depuração no registro de depuração.

  1. Execute este exemplo na janela Executar anônimo no 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. Verifique as mensagens de depuração (use a palavra-chave DEBUG para o filtro).
    Uma falha deve ser reportada e três contatos devem ter sido inseridos.

Você deve usar instruções DML ou métodos Database?

  • Use instruções DML se quiser que qualquer erro que ocorra durante o processamento DML em massa seja gerado como uma exceção do Apex que interrompe imediatamente o fluxo de controle (usando blocos try...catch). Esse comportamento é similar à maneira como exceções são tratadas na maioria das linguagens de procedimento de bancos de dados.
  • Use métodos de classe Database se quiser permitir o sucesso parcial de uma operação DML em massa — se um registro falhar, o restante da operação DML ainda pode ser bem-sucedida. Seu aplicativo pode então inspecionar os registros rejeitados e possivelmente tentar efetuar a operação novamente. Ao utilizar esse formato, você pode escrever um código que nunca gere erros de exceção de DML. Em vez disso, seu código pode usar a matriz de resultados apropriada para julgar o sucesso ou a falha. Observe que métodos Database também incluem uma sintaxe compatível com exceções geradas, semelhante às instruções DML.

Crie e gerencie registros vinculados por relacionamentos.

Inserir registros relacionados

Você pode inserir registros relacionados nos registros existentes caso um relacionamento já tenha sido definido entre os dois objetos, por exemplo, um relacionamento de pesquisa ou um relacionamento entre mestre e detalhes. Um registro é associado a um registro relacionado por um ID de chave estrangeira. Por exemplo, ao inserir um novo contato, é possível especificar o registro de conta relacionado ao contato definindo o valor do campo AccountId.

Esse exemplo mostra como adicionar um contato a uma conta (o registro relacionado) definindo o campo AccountId do contato. O contato e a conta são vinculados por um relacionamento de pesquisa.

  1. Execute este trecho de código na janela Apex anônimo do 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. Inspecione os contatos da sua organização.
    Uma nova conta (conta SFDC) foi criada, e o contato Mario Ruiz está na lista relacionada Contatos dessa conta.

Atualizar registros relacionados

Não é possível atualizar os campos dos registros relacionados com a mesma chamada para a operação DML. Isso exige uma chamada DML à parte. Por exemplo, ao inserir um novo contato, é possível especificar o registro de conta relacionado ao contato definindo o valor do campo AccountId. No entanto, não pode alterar o nome da conta sem atualizar a própria conta com uma chamada DML à parte. De modo parecido, ao atualizar um contato, você precisa fazer duas chamadas DML se também quiser atualizar a conta relacionada ao contato. O exemplo a seguir atualiza um contato e a conta relacionada a ele usando duas instruções update (atualizar).

// 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;

Excluir registros relacionados

A operação delete permite exclusões em cascata. Quando um objeto pai é excluído, excluem-se automaticamente todos os registros filhos relacionados a ele que puderem ser excluídos.

Por exemplo, se você excluir a conta criada anteriormente (conta SFDC), também excluirá o contato relacionado a ela.

  1. Execute este trecho de código na janela Apex anônimo do Developer Console.
    Account[] queriedAccounts = [SELECT Id FROM Account WHERE Name='SFDC Account'];
    delete queriedAccounts;
  2. Verifique as contas e contatos em sua organização.
    Você verá que tanto a conta quanto seu contato relacionado foram excluídos.

Sobre as transações

As operações DML são executadas dentro de uma transação. Todas as operações DML em uma transação são concluídas com êxito ou, se um erro ocorrer em uma operação, a transação inteira será revertida e nenhum dado será confirmado no banco de dados. O limite de uma transação pode ser um acionador, um método de classe, um bloco anônimo de código, uma página do Apex ou um método de serviço da Web personalizado. Por exemplo, se um acionador ou uma classe criar duas contas e atualizar um contato, mas a atualização do contato falhar por causa de um erro na regra de validação, a transação inteira será revertida e nenhuma das contas permanecerá no Salesforce.

Recursos

Compartilhe seu feedback do Trailhead usando a Ajuda do Salesforce.

Queremos saber sobre sua experiência com o Trailhead. Agora você pode acessar o novo formulário de feedback, a qualquer momento, no site Ajuda do Salesforce.

Saiba mais Continue compartilhando feedback