Votre requête SOQL peut renvoyer de nombreux sObjects qui dépassent la limite de la taille de segment mémoire et génèrent une erreur. Pour la résoudre, utilisez une boucle for de requête SOQL, qui peut traiter plusieurs lots d'enregistrements en utilisant des appels internes à query et à queryMore.
Par exemple, si les résultats sont trop grands, la syntaxe ci-dessous peut entraîner une exception d'exécution.
Account[] accts = [SELECT Id FROM Account];
À la place, utilisez une boucle for de requête SOQL dans l'un des exemples ci-dessous :
// Use this format if you are not executing DML statements
// within the for loop
for (Account a : [SELECT Id, Name FROM Account WHERE Name LIKE 'Acme%']) { // Your code without DML statements here } // Use this format for efficiency if you are executing DML statements
// within the for loop
for (List<Account> accts : [SELECT Id, Name FROM Account WHERE Name LIKE 'Acme%']) { // Your code here
update accts; }
L'exemple suivant montre une boucle for de requête SOQL utilisée pour mettre à jour en masse les enregistrements. Supposons que vous souhaitez modifier le nom de contact dans tous les enregistrements de contact dont le nom et le prénom correspondent à un critère spécifique :
public void massUpdate() { for (List<Contact> contacts: [SELECT FirstName, LastName FROM Contact]) { for(Contact c : contacts) { if (c.FirstName == 'Barbara' && c.LastName == 'Gordon') { c.LastName = 'Wayne'; } } update contacts; } }
Au lieu d'utiliser une requête SOQL dans une boucle for, la méthode recommandée de mise à jour en masse des enregistrements consiste à utiliser Apex par lot, qui réduit les risques d'atteindre les limitations du gouverneur.
Pour plus informations, reportez-vous à Boucles For SOQL.
Pour de meilleures performances, les requêtes SOQL doivent être sélectives, notamment pour les requêtes dans des déclencheurs. Pour éviter les délais d'exécution importants, les requêtes SOQL non sélectives peuvent être terminées par le système. Les développeurs reçoivent un message d'erreur lorsqu'une requête non sélective dans un déclencheur est exécutée sur un objet qui contient plus de 100 000 enregistrements. Pour éviter cette erreur, assurez-vous d'utiliser une requête sélective.
Cependant, il existe d'autres scénarios complexes dans lesquels les index personnalisés ne sont pas utilisés. Si votre cas n'est pas mentionné ici ou si vous souhaitez obtenir une aide supplémentaire sur les requêtes non sélectives, contactez votre représentant salesforce.com.
SELECT Id FROM Account WHERE Id IN (<list of account IDs>)
La clause WHERE se trouve dans un champ indexé (ID). Si SELECT COUNT() FROM Account WHERE Id IN (<list of account IDs>) renvoie un nombre d'enregistrements inférieur au seuil de sélectivité, l'index dans ID est utilisé. Ce cas est le plus fréquent, car la liste d'ID contient une faible quantité d'enregistrements.
SELECT Id FROM Account WHERE Name != ''
Puisque Account est un objet volumineux, même si Name est indexé (clé primaire), ce filtre renvoie la plupart des enregistrements, rendant la requête non sélective.
SELECT Id FROM Account WHERE Name != '' AND CustomField__c = 'ValueA'
Ici nous devons déterminer si chaque filtre, considéré individuellement, est sélectif. Comme nous l'avons vu dans l'exemple précédent, le premier filtre n'est pas sélectif. Examinons le deuxième. Si le nombre d'enregistrements renvoyé par SELECT COUNT() FROM Account WHERE CustomField__c = 'ValueA' est inférieur au seuil de sélectivité, et que CustomField__c est indexé, la requête est sélective.