Skip to main content

Scrivere query SOQL

Obiettivi di apprendimento

Al completamento di questa unità, sarai in grado di:
  • Scrivere query SOQL in Apex.
  • Eseguire query SOQL utilizzando Query Editor nella Developer Console.
  • Eseguire query SOQL integrate in Apex utilizzando l'esecuzione Apex anonima.
  • Eseguire query su record correlati.
Nota

Nota

Stai seguendo la formazione in italiano? In questo badge, la convalida delle sfide pratiche di Trailhead funziona in inglese. Le traduzioni sono fornite tra parentesi come riferimento. Nel tuo Trailhead Playground, accertati di (1) selezionare Stati Uniti per le impostazioni internazionali, (2) impostare la lingua su Inglese e (3) copiare e incollare soltanto i valori in lingua inglese. Segui le istruzioni qui.

Visita il badge Trailhead nella tua lingua per scoprire come usufruire dell'esperienza di Trailhead in altre lingue.

Iniziare a utilizzare SOQL

Per leggere un record su Salesforce, è necessario scrivere una query. Salesforce mette a disposizione il Salesforce Object Query Language, o SOQL in breve, che è possibile utilizzare per leggere i record salvati. SOQL è simile al linguaggio SQL standard ma è personalizzato per Lightning Platform.

Poiché Apex ha accesso diretto ai record di Salesforce memorizzati nel database, è possibile incorporare le query SOQL nel codice Apex utilizzato e ottenere i risultati in modo diretto. Quando SOQL viene incorporato in Apex, viene definito SOQL inline.

Per includere le query SOQL nel codice Apex, occorre inserire l'istruzione SOQL tra parentesi quadre e assegnare il valore restituito a un array di sObject. Ad esempio, nel seguente esempio vengono recuperati tutti i record di account con due campi, Name e Phone, e viene restituito un array di sObject Account.
Account[] accts = [SELECT Name,Phone FROM Account];

Prerequisiti

Alcune query di questa unità prevedono che l'organizzazione disponga di account e referenti. Prima di eseguire le query, bisogna creare dei dati di esempio.

  1. Nella Developer Console, apri la finestra Execute Anonymous (Esecuzione anonima) nel menu Debug.
  2. Inserisci nella finestra lo snippet riportato di seguito e fai clic su Execute (Esegui).
// 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;
Nota

Il campo Name dell'sObject Contact è un campo composto. Si tratta di una concatenazione dei campi FirstName, LastName, MiddleName e Suffix dell'oggetto Contact. Nell'Object Manager (Gestore oggetti) di Setup (Imposta) è riportato soltanto il campo composto Name (Nome). Tuttavia, il codice APEX di esempio di questa unità fa riferimento ai singoli campi da cui è formato il campo composto.

Utilizzare Query Editor

La Developer Console offre la console Query Editor, che permette di eseguire le query SOQL e visualizzare i risultati. Query Editor è uno strumento che consente di ispezionare rapidamente il database. È un valido strumento per testare le query SOQL prima di aggiungerle al codice Apex. Quando si utilizza Query Editor, è necessario fornire solo l'istruzione SOQL senza il codice Apex in cui è inserita.

Proviamo a eseguire il seguente esempio di SOQL:

  1. Nella Developer Console, fai clic sulla scheda Query Editor.
  2. Copia e incolla quanto segue nella prima casella di Query Editor, quindi fai clic su Execute (Esegui).
SELECT Name,Phone FROM Account

Tutti i record degli account dell'organizzazione sono visualizzati nella sezione Query Results (Risultati della query) come righe con campi.

Sintassi SOQL di base

Questa è la sintassi di una query SOQL di base:

SELECT fields FROM ObjectName [WHERE Condition]

La clausola WHERE è facoltativa. Iniziamo con una query molto semplice. Ad esempio, la query seguente recupera gli account e ottiene i campi Name e Phone per ciascuno di essi.

SELECT Name,Phone FROM Account

La query si compone di due parti:

  1. SELECT Name,Phone: questa parte riporta i campi che si vogliono recuperare. I campi sono specificati dopo la parola chiave SELECT in un elenco delimitato da virgole. In alternativa, è possibile specificare un solo campo, nel qual caso non è necessaria la virgola (ad es. SELECT Phone).
  2. FROM Account: questa parte specifica l'oggetto standard o personalizzato che si vuole recuperare. In questo esempio, si tratta di Account. Per un oggetto personalizzato chiamato Estratto_conto, sarebbe Estratto_conto__c.
Nota

Oltre i concetti di base

A differenza di altri linguaggi SQL, non è possibile specificare * per indicare tutti i campi. È necessario specificare esplicitamente tutti i campi che si desiderano ottenere. Se si cerca di accedere a un campo che non è stato specificato nella clausola SELECT, si otterrà un errore perché il campo non è stato recuperato.

Non occorre specificare il campo Id nella query perché viene sempre restituito nelle query Apex, a prescindere dal fatto che sia specificato o meno nella query. Ad esempio: SELECT Id,Phone FROM Account e SELECT Phone FROM Account sono istruzioni equivalenti. L'unico caso in cui è necessario specificare il campo Id è quando si tratta dell'unico campo che si sta recuperando, perché è necessario indicare almeno un campo: SELECT Id FROM Account. È consigliabile specificare il campo Id anche quando si esegue una query in Query Editor, poiché il campo ID non verrà visualizzato se non viene specificato.

Filtrare i risultati delle query con le condizioni

Se nell'organizzazione ci sono più account, verranno restituiti tutti. Se desideri limitare gli account restituiti a quelli che soddisfano una determinata condizione, puoi aggiungere tale condizione all'interno della clausola WHERE. Nell'esempio riportato di seguito vengono recuperati solo gli account il cui nome è SFDC Computing. Tieni presente che i confronti tra stringhe non fanno distinzione tra maiuscole e minuscole.

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

La clausola WHERE può contenere più condizioni che vengono raggruppate utilizzando gli operatori logici (AND, OR) e le parentesi. Ad esempio, questa query restituisce tutti gli account il cui nome è SFDC Computing e che hanno più di 25 dipendenti:

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

Ecco un altro esempio con una condizione più complessa. Questa query restituisce tutti questi record:

  • Tutti gli account SFDC Computing
  • Tutti gli account con più di 25 dipendenti la cui città di fatturazione è Los Angeles
SELECT Name,Phone FROM Account WHERE (Name='SFDC Computing' OR (NumberOfEmployees>25 AND BillingCity='Los Angeles'))
Nota

Oltre i concetti di base

Anziché utilizzare l'operatore "uguale a" (=) per il confronto, è possibile eseguire delle corrispondenze "fuzzy" utilizzando l'operatore LIKE. Ad esempio, è possibile recuperare tutti gli account il cui nome inizia con SFDC utilizzando questa condizione: WHERE Name LIKE 'SFDC%'. Il carattere jolly % indica qualsiasi carattere o nessun carattere. Il carattere _, invece, può essere utilizzato per eseguire il confronto su un solo carattere.

Ordinare i risultati delle query

Quando una query viene eseguita, restituisce i record da Salesforce senza un ordine particolare, quindi non puoi fare affidamento sul fatto che l'ordine dei record nell'array restituito sia lo stesso ogni volta che la query viene eseguita. Tuttavia, puoi scegliere di ordinare l'insieme di record restituiti aggiungendo una clausola ORDER BY e specificando il campo in base al quale l'insieme di record deve essere ordinato. In questo esempio tutti gli account recuperati vengono ordinati in base al campo Name.

SELECT Name,Phone FROM Account ORDER BY Name

L'ordinamento predefinito è quello alfabetico, specificato come ASC. L'istruzione precedente è equivalente a:

SELECT Name,Phone FROM Account ORDER BY Name ASC

Per invertire l'ordine, usa la parola chiave DESC per indicare l'ordine discendente:

SELECT Name,Phone FROM Account ORDER BY Name DESC

È possibile ordinare la maggior parte dei campi, compresi quelli numerici e testuali. Non è possibile ordinare i campi come il testo RTF e gli elenchi di selezione a selezione multipla.

Prova queste istruzioni SOQL in Query Editor e osserva come cambia l'ordine dei record restituiti in base al campo Name.

Limitare il numero di record restituiti

È possibile limitare il numero di record restituiti a un numero arbitrario aggiungendo la clausola LIMIT n, dove n è il numero di record che si desidera vengano restituiti. Limitare l'insieme dei risultati torna utile quando non interessa quali record vengono restituiti, ma si desidera lavorare solo con un sottoinsieme di record. Ad esempio, questa query recupera il primo account che viene restituito. Com'è possibile notare, il valore restituito è un solo account e non un array quando si utilizza la clausola LIMIT 1.

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

Combinare tutti gli elementi

È possibile mettere insieme le clausole opzionali in un'unica query, nel seguente ordine:

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

Esegui in Apex la query SOQL riportata di seguito, utilizzando la finestra Execute Anonymous (Esecuzione anonima) della Developer Console. Quindi controlla le istruzioni di debug nel registro di debug. Dovrebbe essere restituito un solo account di esempio.

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

Accedere alle variabili nelle query SOQL

Le istruzioni SOQL in Apex possono fare riferimento a variabili ed espressioni di codice Apex se sono precedute dai due punti (:). Il ricorso a una variabile locale all'interno di un'istruzione SOQL si chiama bind.

Questo esempio mostra come utilizzare la variabile targetDepartment nella clausola WHERE.

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

Eseguire query su record correlati

I record in Salesforce possono essere collegati tra loro attraverso relazioni: relazioni di ricerca o relazioni record principale-record dettaglio. Ad esempio, il Referente ha una relazione di ricerca con l'Account. Quando si crea o si aggiorna un referente, è possibile associarlo a un account. I referenti associati allo stesso account vengono visualizzati in un elenco correlato nella pagina dell'account. Così come puoi visualizzare i record correlati nell'interfaccia utente di Salesforce, allo stesso modo puoi eseguire query su record correlati in SOQL.

Per recuperare i record secondari correlati a un record principale, aggiungi una query interna per i record secondari. La clausola FROM della query interna viene eseguita in base al nome della relazione, anziché al nome dell'oggetto Salesforce. Questo esempio contiene una query interna per ottenere tutti i referenti associati a ciascun account restituito. La clausola FROM specifica la relazione Contacts, una relazione predefinita su Account che collega account e referenti.

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

Nel prossimo esempio, incorporiamo la query SOQL di esempio in Apex e mostriamo come ottenere i record secondari dal risultato SOQL utilizzando il nome della relazione Contacts dell'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);

È possibile attraversare una relazione da un oggetto secondario (Contact) a un campo del rispettivo oggetto principale (Account.Name) utilizzando la notazione con punti. Ad esempio, il seguente snippet Apex esegue una query sui record dei referenti il cui nome è Carol ed è in grado di recuperare il nome dell'account associato a Carol attraversando la relazione tra account e referenti.

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

Gli esempi di questa sezione si basano su oggetti standard. Gli oggetti personalizzati possono essere collegati tra loro anche utilizzando le relazioni personalizzate. I nomi delle relazioni personalizzate terminano con il suffisso __r. Ad esempio, gli estratti conto sono collegati alle singole voci attraverso la relazione Singole_voci__r nell'oggetto personalizzato Estratto_conto__c.

Eseguire query su record in batch utilizzando i loop for SOQL

Con un loop for SOQL, è possibile includere una query SOQL all'interno del loop for. L'iterazione dei risultati di una query SOQL può avvenire all'interno del loop. I loop for SOQL utilizzano un metodo diverso per recuperare i record: i record vengono recuperati utilizzando una suddivisione in blocchi efficiente con chiamate ai metodi query e queryMore dell'API SOAP. Utilizzando i loop for SOQL, è possibile evitare di raggiungere il limite delle dimensioni dell'heap.

L'iterazione dei loop for SOQL avviene su tutti i record sObject restituiti da una query SOQL. La sintassi di un loop for SOQL è una delle seguenti:
for (variable : [soql_query]) {
    code_block
}
oppure
for (variable_list : [soql_query]) {
    code_block
}

Sia variable che variable_list devono essere dello stesso tipo degli sObject restituiti dalla soql_query.

È preferibile utilizzare il formato dell'elenco sObject del loop for SOQL, in quanto il loop viene eseguito una sola volta per ogni batch di 200 sObject. In questo modo è possibile lavorare su batch di record ed eseguire operazioni DML in batch, evitando così di raggiungere i limiti del governor.

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
Continua a imparare gratuitamente!
Registra un account per continuare.
Cosa troverai?
  • Ottieni consigli personalizzati per i tuoi obiettivi di carriera
  • Metti in pratica le tue competenze con sfide pratiche e quiz
  • Monitora e condividi i tuoi progressi con i datori di lavoro
  • Accedi a risorse di tutoraggio e opportunità di carriera