Skip to main content

Escrever consultas SOQL

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:
  • Escrever consultas SOQL no Apex.
  • Executar consultas SOQL utilizando o Editor de consulta no Developer Console.
  • Executar consultas SOQL integradas ao Apex utilizando Apex anônimo.
  • Registros relacionados a consultas.
Nota

Nota

Deseja aprender em português (Brasil)? Nesse emblema, as validações dos desafios práticos do Trailhead funcionam em inglês. As traduções são fornecidas entre parênteses como referência No Trailhead Playground, (1) mude a localidade para Estados Unidos, (2) mude o idioma para inglês e (3) copie e cole apenas os valores em inglês. Siga as instruções aqui.

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

Introdução ao SOQL

Para ler um registro do Salesforce, você precisa escrever uma consulta. O Salesforce fornece o Salesforce Object Query Language (SOQL), que você pode usar para ler registros salvos. A SOQL é semelhante à linguagem SQL padrão, mas é personalizada para a Lightning Platform.

Como o Apex tem acesso direto aos registros do Salesforce que são armazenados no banco de dados, você pode incorporar consultas SOQL em seu código do Apex e obter resultados de forma simples. Quando o SOQL é incorporado ao Apex, é referenciado como SOQL embutida.

Para incluir consultas SOQL dentro do seu código do Apex, coloque a instrução SOQL entre colchetes e atribua o valor de retorno a uma matriz de sObjects. Por exemplo, o seguinte recupera todos os registros de conta que tenham dois campos – nome e telefone – e retorna uma matriz de sObjects da conta.
Account[] accts = [SELECT Name,Phone FROM Account];

Pré-requisitos

Algumas consultas nesta unidade esperam que a organização tenha contas e contatos. Antes de executar as consultas, crie alguns dados de amostra.

  1. No Console do desenvolvedor, abra a janela Executar anônimo no menu Depurar.
  2. Insira o trecho de código abaixo na janela e clique em Executar.
// Add account and related contact
Account acct = new Account(
    Name='SFDC Computing',
    Phone='(415)555-1212',
    NumberOfEmployees=50,
    BillingCity='San Francisco');
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 con = new Contact(
    FirstName='Carol',
    LastName='Ruiz',
    Phone='(415)555-1212',
    Department='Wingo',
    AccountId=acctID);
insert con;
// Add account with no contact
Account acct2 = new Account(
    Name='The SFDC Query Man',
    Phone='(310)555-1213',
    NumberOfEmployees=50,
    BillingCity='Los Angeles',
    Description='Expert in wing technologies.');
insert acct2;
Observação

O campo de nome do sObject Contato é um campo composto. É uma concatenação dos campos FirstName, LastName, MiddleName e Suffix do contato. O Gerenciador de objetos em Configuração lista somente o campo de nome composto. Mas nosso exemplo de código do Apex nesta unidade faz referência aos campos individuais que formam o campo composto.

Usar o editor de consulta

O Developer Console fornece o console do Editor de consulta, que permite executar consultas SOQL e exibir os resultados. O Editor de consulta oferece uma forma rápida de inspecionar o banco de dados. É uma boa maneira de testar as consultas SOQL antes de adicioná-las ao seu código do Apex. Ao usar o Editor de consulta, é obrigatório fornecer apenas a instrução SOQL, sem o código do Apex que a rodeia.

Tente executar o seguinte exemplo de SOQL:

  1. No Console do desenvolvedor, clique na guia Editor de consulta.
  2. Copie e cole o seguinte no primeiro campo do Editor de consulta e, em seguida, clique em Executar.
SELECT Name,Phone FROM Account

Todos os registros de conta da sua organização são exibidos na seção Query Results (Resultados da consulta) como linhas com campos.

Sintaxe básica SOQL

Esta é a sintaxe de uma consulta SOQL básica:

SELECT fields FROM ObjectName [WHERE Condition]

A cláusula WHERE é opcional. Vamos começar com uma consulta muito simples. Por exemplo, a consulta a seguir recupera contas e obtém os campos Nome e Telefone para cada conta.

SELECT Name,Phone FROM Account

A consulta tem duas partes:

  1. SELECT Name,Phone: Esta parte lista os campos que você gostaria de recuperar. Os campos são especificados depois da palavra-chave SELECT em uma lista delimitada por vírgula. Ou você pode especificar apenas um campo; nesse caso, nenhuma vírgula é necessária (por exemplo, SELECT Phone).
  2. FROM Account: Esta parte especifica o objeto personalizado ou padrão que você deseja recuperar. Neste exemplo, é Conta. Para um objeto personalizado chamado Invoice_Statement, é Invoice_Statement__c.
Observação

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

Ao contrário de outras linguagens SQL, você não pode especificar * para todos os campos. É necessário especificar explicitamente todos os campos que você deseja obter. Se tentar acessar um campo que não tenha especificado na cláusula SELECT, você obterá um erro porque o campo não foi recuperado.

Não é necessário especificar o campo ID na consulta, pois ele sempre retorna em consultas do Apex, independentemente se for especificado na consulta ou não. Por exemplo: SELECT Id,Phone FROM Account e SELECT Phone FROM Account são instruções equivalentes. Você pode querer especificar o campo ID se ele for o único campo recuperado porque você precisa listar pelo menos um campo: SELECT Id FROM Account. Você pode querer especificar o campo ID também ao executar uma consulta no Editor de consulta, pois o campo ID não será exibido a menos que especificado.

Filtrar resultados de consultas com condições

Se você tiver mais de uma conta na organização, todas elas serão retornadas. Se quiser limitar as contas retornadas para contas que cumprem uma determinada condição, você pode adicionar essa condição dentro da cláusula WHERE. O exemplo a seguir recupera apenas as contas cujos nomes são SFDC Computing. Observe que as comparações nas strings não diferenciam caracteres maiúsculos e minúsculos.

SELECT Name,Phone FROM Account WHERE Name='SFDC Computing'

A cláusula WHERE pode conter várias condições que são agrupadas usando operadores lógicos (AND, OR) e parênteses. Por exemplo, esta consulta retorna todas as contas com o nome SFDC Computing que tenham mais de 25 funcionários:

SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)

Temos agora outro exemplo com uma condição mais complexa. Esta consulta retorna todos esses registros:

  • Todas as contas SFDC Computing
  • Todas as contas com mais de 25 funcionários cuja cidade de faturamento seja Los Angeles
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))
Observação

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

Em vez de usar o operador de igual (=) para comparação, você pode executar correspondências difusas usando o operador LIKE. Por exemplo, você pode recuperar todas as contas cujos nomes começam com SFDC usando esta condição: WHERE Name LIKE 'SFDC%'. O caractere curinga % corresponde a um ou nenhum caractere. Em contraste, o caractere _ pode ser usado para corresponder a apenas um caractere.

Ordenar os resultados da consulta

Quando uma consulta é executada, ela não retorna os registros do Salesforce em uma ordem específica, então não dá para confiar que a ordem dos registros da matriz retornada seja a mesma sempre que a consulta for executada. No entanto, você pode optar por classificar o registro retornado adicionando uma cláusula ORDER BY e especificando o campo pelo qual o conjunto de registros deve ser classificado. O exemplo a seguir classifica todas as contas recuperadas com base no campo de nome.

SELECT Name,Phone FROM Account ORDER BY Name

A ordem de classificação padrão é a ordem alfabética, especificada como ASC. A instrução anterior é equivalente a:

SELECT Name,Phone FROM Account ORDER BY Name ASC

Para inverter a ordem, use a palavra-chave DESC para ordem decrescente:

SELECT Name,Phone FROM Account ORDER BY Name DESC

Você pode classificar a maioria dos campos, inclusive campos numéricos e de texto. Não é possível classificar campos como o rich text e listas de opções de seleção múltipla.

Experimente estas instruções SOQL no Editor de consulta e veja como a ordem do registro retornado muda de acordo com o campo de nome.

Limitar o número de registros retornados

Você pode limitar o número de registros retornados a um número arbitrário, adicionando a cláusula LIMIT n, em que n é o número de registros que você deseja obter. Limitar o conjunto de resultados é útil quando os tipos de registros retornados não importam, e você apenas deseja trabalhar com um subconjunto de registros. Por exemplo, esta consulta recupera a primeira conta que é retornada. Observe que o valor retornado é uma conta e não uma matriz quando LIMIT 1 é usado.

Account oneAccountOnly = [SELECT Name,Phone FROM Account LIMIT 1];

Juntar todas as peças

É possível combinar as cláusulas opcionais em uma consulta, na seguinte ordem:

SELECT Name,Phone FROM Account 
                   WHERE (Name = 'SFDC Computing' AND NumberOfEmployees>25)
                   ORDER BY Name
                   LIMIT 10

Execute a seguinte consulta SOQL no Apex usando a janela Execute Anonymous (Executar anônimo) do Developer Console. Em seguida, inspecione as instruções de depuração no registro de depuração. Uma conta de exemplo será retornada.

Account[] accts = [SELECT Name,Phone FROM Account 
                   WHERE (Name='SFDC Computing' AND NumberOfEmployees>25)
                   ORDER BY Name
                   LIMIT 10];
System.debug(accts.size() + ' account(s) returned.');
// Write all account array info
System.debug(accts);

Acessar variáveis em consultas SOQL

As instruções SOQL no Apex podem referenciar expressões e variáveis de código do Apex se forem precedidas por dois pontos (:). O uso de uma variável local dentro de uma instrução SOQL é chamado de vínculo.

Este exemplo mostra como usar a variável targetDepartment na cláusula WHERE.

String targetDepartment = 'Wingo';
Contact[] techContacts = [SELECT FirstName,LastName 
                          FROM Contact WHERE Department=:targetDepartment];

Consultar registros relacionados

Os registros no Salesforce podem ser ligados uns aos outros por meio de relacionamentos: relacionamentos de pesquisa ou relacionamentos entre mestre e detalhes. Por exemplo, o Contato possui um relacionamento de pesquisa com a Conta. Ao criar ou atualizar um contato, você pode associá-lo a uma conta. Os contatos associados à mesma conta aparecem em uma lista relacionada na página da conta. Assim como é possível visualizar os registros relacionados na interface de usuário do Salesforce, você pode consultar os registros relacionados na SOQL.

Para obter registros filhos relacionados a um registro pai, adicione uma consulta interna para os registros filhos. A cláusula FROM da consulta interna é executada em relação ao nome do relacionamento e não ao nome de um objeto do Salesforce. O exemplo a seguir contém uma consulta interna para obter todos os contatos que estão associados a cada conta retornada. A cláusula FROM especifica o relacionamento Contatos, que é um relacionamento padrão na Conta que liga contas e contatos.

SELECT Name, (SELECT LastName FROM Contacts) FROM Account WHERE Name = 'SFDC Computing'

O próximo exemplo incorpora a consulta SOQL de exemplo no Apex e mostra como obter os registros filhos do resultado da SOQL usando o nome do relacionamento Contatos no sObject.

Account[] acctsWithContacts = [SELECT Name, (SELECT FirstName,LastName FROM Contacts)
                               FROM Account 
                               WHERE Name = 'SFDC Computing'];
// Get child records
Contact[] cts = acctsWithContacts[0].Contacts;
System.debug('Name of first associated contact: ' 
             + cts[0].FirstName + ', ' + cts[0].LastName);

Você pode percorrer um relacionamento de um objeto filho (contato) a um campo de seu pai (Account.Name) usando a notação de ponto. Por exemplo, o trecho de código Apex a seguir consulta os registros de contatos cujo primeiro nome é Carol e consegue recuperar o nome da conta associada da Carol percorrendo o relacionamento entre contas e contatos.

Contact[] cts = [SELECT Account.Name FROM Contact 
                 WHERE FirstName = 'Carol' AND LastName='Ruiz'];
Contact carol = cts[0];
String acctName = carol.Account.Name;
System.debug('Carol\'s account name is ' + acctName);
Nota

Nota

Os exemplos desta seção se baseiam em objetos padrão. Os objetos personalizados também podem ser ligados entre si por meio de relacionamentos personalizados. Os nomes dos relacionamentos personalizados terminam com o sufixo __r. Por exemplo, os demonstrativos de faturas estão ligados a itens de linha por meio do relacionamento Line_Items__r sobre o objeto personalizado Invoice_Statement__c.

Consultar registros em lotes usando loops for SOQL

Com um loop for SOQL, você pode incluir uma consulta SOQL em um loop for. Os resultados de uma consulta SOQL podem ser iterados dentro do loop. Os loops for SOQL usam um método diferente para recuperar registros; os registros são recuperados por meio de agrupamento eficiente, com chamadas para a consulta e métodos queryMore da API SOAP. Usando os loops for SOQL, você pode evitar bater o limite de tamanho do heap.

Os loops for SOQL iteram sobre todos os registros sObject retornados por uma consulta SOQL. A sintaxe de um loop for SOQL pode ser:
for (variable : [soql_query]) {
    code_block
}
ou
for (variable_list : [soql_query]) {
    code_block
}

Tanto variable quanto variable_list devem ser do mesmo tipo que os sObjects retornados pela soql_query.

É preferível usar o formato de lista sObject do loop for SOQL, pois o loop é executado uma vez para cada lote de 200 sObjects. Dessa forma, você pode trabalhar em lotes de registros e executar operações DML em lote, o que ajuda a evitar atingir os limites de administrador.

insert new Account[]{new Account(Name = 'for loop 1'), 
                     new Account(Name = 'for loop 2'), 
                     new Account(Name = 'for loop 3')};
// The sObject list format executes the for loop once per returned batch
// of records
Integer i=0;
Integer j=0;
for (Account[] tmp : [SELECT Id FROM Account WHERE Name LIKE 'for loop _']) {
    j = tmp.size();
    i++;
}
System.assertEquals(3, j); // The list should have contained the three accounts
                       // named 'yyy'
System.assertEquals(1, i); // Since a single batch can hold up to 200 records and,
                       // only three records should have been returned, the 
                       // loop should have executed only once
Continue a aprender de graça!
Inscreva-se em uma conta para continuar.
O que você ganha com isso?
  • Receba recomendações personalizadas para suas metas de carreira
  • Pratique suas habilidades com desafios práticos e testes
  • Monitore e compartilhe seu progresso com os empregadores
  • Conecte-se a orientação e oportunidades de carreira