function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mr360Ajmr360Aj 

how to solve too many soql queries 101 error in apex class?

csvFileLines = csvAsString.split('\n');
                    
                    for(Integer i=1; i < csvFileLines.size(); i++){
                        String csvLine = csvFileLines[i];
                    
                        List<String> csvRecordData = new List<String>();
                        
                        for(String column : csvLine.split(',')){
    
                            column = column.replaceAll(':quotes:', '');
                            column = column.replaceAll(':comma:', ',');
                            column = column.replaceAll(':newLine:', '\n');
    
                            csvRecordData.add(column);
                        }     
                        
                        IF(csvRecordData != Null){
                            
                            FeedItem cmnt = New FeedItem();       
   
                            cmnt.Body = csvRecordData[2].replaceAll('<br />', '\r\n');
                            
                            Datetime createDate = DateTime.valueOfGmt(csvRecordData[4]); 
                            cmnt.CreatedDate = createDate;
                               
                            String iv = csvRecordData[1];
                            if(!String.isEmpty(iv)){
                                Lead ld = Database.query('SELECT id, import_id__c FROM User WHERE import_id__c = :iv');
                                cmnt.ParentId = ld.Id;
                               }
                            
                            cmntlist.add(cmnt);
                            
                        }
                    }
Best Answer chosen by mr360Aj
SwethaSwetha (Salesforce Developers) 
HI Ajay,

The "Too many SOQL queries: 101" error occurs when we exceed the Salesforce governor limit of 100 SOQL queries in a single call or context.

To resolve this error, we need to optimize our code to reduce the number of SOQL queries being executed. Some best practices to follow are:

> Instead of querying inside a loop, we can query outside the loop and store the results in a list or map. We can then iterate over the list or map to perform any necessary operations.
> SOQL for loops are a more efficient way to process large amounts of data. They allow us to process records in batches of 200, reducing the number of SOQL queries executed.
>We can use collections such as lists and maps to store data and perform operations on them. This can help reduce the number of SOQL queries executed.
>If we are working with triggers, we can bulkify them to process records in batches. This can help reduce the number of SOQL queries executed.
> We can use @future methods to perform long-running operations asynchronously. This can help reduce the number of SOQL queries executed in the current transaction.

I've made some changes to your code as
// Fetch all import_id__c values first
Set<String> importIds = new Set<String>();
for (Integer i = 1; i < csvFileLines.size(); i++) {
    String csvLine = csvFileLines[i];
    List<String> csvRecordData = new List<String>();
    for (String column : csvLine.split(',')) {
        column = column.replaceAll(':quotes:', '');
        column = column.replaceAll(':comma:', ',');
        column = column.replaceAll(':newLine:', '\n');
        csvRecordData.add(column);
    }
    
    if (csvRecordData.size() > 1) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv)) {
            importIds.add(iv);
        }
    }
}

// Query Leads with matching import_id__c values
Map<String, Lead> importIdToLeadMap = new Map<String, Lead>();
for (Lead ld : [SELECT Id, import_id__c FROM Lead WHERE import_id__c IN :importIds]) {
    importIdToLeadMap.put(ld.import_id__c, ld);
}

// Process the CSV data and create FeedItems
for (Integer i = 1; i < csvFileLines.size(); i++) {
    String csvLine = csvFileLines[i];
    List<String> csvRecordData = new List<String>();
    for (String column : csvLine.split(',')) {
        column = column.replaceAll(':quotes:', '');
        column = column.replaceAll(':comma:', ',');
        column = column.replaceAll(':newLine:', '\n');
        csvRecordData.add(column);
    }
    
    if (csvRecordData.size() > 4) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv) && importIdToLeadMap.containsKey(iv)) {
            FeedItem cmnt = new FeedItem();
            cmnt.Body = csvRecordData[2].replaceAll('<br />', '\r\n');
            cmnt.CreatedDate = DateTime.valueOfGmt(csvRecordData[4]);
            cmnt.ParentId = importIdToLeadMap.get(iv).Id;
            cmntlist.add(cmnt);
        }
    }
}

If this information helps, please mark the answer as best. Thank you

All Answers

SwethaSwetha (Salesforce Developers) 
HI Ajay,

The "Too many SOQL queries: 101" error occurs when we exceed the Salesforce governor limit of 100 SOQL queries in a single call or context.

To resolve this error, we need to optimize our code to reduce the number of SOQL queries being executed. Some best practices to follow are:

> Instead of querying inside a loop, we can query outside the loop and store the results in a list or map. We can then iterate over the list or map to perform any necessary operations.
> SOQL for loops are a more efficient way to process large amounts of data. They allow us to process records in batches of 200, reducing the number of SOQL queries executed.
>We can use collections such as lists and maps to store data and perform operations on them. This can help reduce the number of SOQL queries executed.
>If we are working with triggers, we can bulkify them to process records in batches. This can help reduce the number of SOQL queries executed.
> We can use @future methods to perform long-running operations asynchronously. This can help reduce the number of SOQL queries executed in the current transaction.

I've made some changes to your code as
// Fetch all import_id__c values first
Set<String> importIds = new Set<String>();
for (Integer i = 1; i < csvFileLines.size(); i++) {
    String csvLine = csvFileLines[i];
    List<String> csvRecordData = new List<String>();
    for (String column : csvLine.split(',')) {
        column = column.replaceAll(':quotes:', '');
        column = column.replaceAll(':comma:', ',');
        column = column.replaceAll(':newLine:', '\n');
        csvRecordData.add(column);
    }
    
    if (csvRecordData.size() > 1) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv)) {
            importIds.add(iv);
        }
    }
}

// Query Leads with matching import_id__c values
Map<String, Lead> importIdToLeadMap = new Map<String, Lead>();
for (Lead ld : [SELECT Id, import_id__c FROM Lead WHERE import_id__c IN :importIds]) {
    importIdToLeadMap.put(ld.import_id__c, ld);
}

// Process the CSV data and create FeedItems
for (Integer i = 1; i < csvFileLines.size(); i++) {
    String csvLine = csvFileLines[i];
    List<String> csvRecordData = new List<String>();
    for (String column : csvLine.split(',')) {
        column = column.replaceAll(':quotes:', '');
        column = column.replaceAll(':comma:', ',');
        column = column.replaceAll(':newLine:', '\n');
        csvRecordData.add(column);
    }
    
    if (csvRecordData.size() > 4) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv) && importIdToLeadMap.containsKey(iv)) {
            FeedItem cmnt = new FeedItem();
            cmnt.Body = csvRecordData[2].replaceAll('<br />', '\r\n');
            cmnt.CreatedDate = DateTime.valueOfGmt(csvRecordData[4]);
            cmnt.ParentId = importIdToLeadMap.get(iv).Id;
            cmntlist.add(cmnt);
        }
    }
}

If this information helps, please mark the answer as best. Thank you
This was selected as the best answer
Arun Kumar 1141Arun Kumar 1141

Hi Ajay,

The Too many SOQL queries error in Apex occurs when your code performs more SOQL (Salesforce Object Query Language) queries than the allowed limits. Salesforce imposes limits on the number of SOQL queries you can execute to prevent excessive usage of resources.

In your code snippet, the issue seems to be with the following line:
 
Lead ld = Database.query('SELECT id, import_id__c FROM User WHERE import_id__c = :iv');

It appears that you are querying the Lead object, but the query is incorrectly targeting the User object. This can cause the error because you might have multiple records in the User object, and the query could potentially return more than one record, which is not allowed when assigning a single Lead variable.

To fix this issue and reduce the number of SOQL queries, you can follow these steps:

1. Make sure you are querying the correct object. In this case, you are looking for a Lead record, not a User record. Update the query to target the Lead object:
 
Lead ld = [SELECT Id, import_id__c FROM Lead WHERE import_id__c = :iv LIMIT 1];

Note that we use the `[SELECT ... FROM ... LIMIT 1]` query to ensure that only one record is returned, as we're expecting a single Lead record with a matching `import_id__c`.

2. Before entering the loop, create a Set to store all the `import_id__c` values you want to search for in the Lead object. Then, you can query all the relevant Lead records at once using a single SOQL query. This will help avoid unnecessary queries in the loop:
 
// Before the loop
Set<String> importIds = new Set<String>();

// Inside the loop
String iv = csvRecordData[1];
if (!String.isEmpty(iv)) {
    importIds.add(iv);
}

// After the loop
List<Lead> leads = [SELECT Id, import_id__c FROM Lead WHERE import_id__c IN :importIds];
Map<String, Id> importIdToLeadIdMap = new Map<String, Id>();
for (Lead lead : leads) {
    importIdToLeadIdMap.put(lead.import_id__c, lead.Id);
}

3. Update the section where you assign the ParentId of the FeedItem:
 
String iv = csvRecordData[1];
if (!String.isEmpty(iv) && importIdToLeadIdMap.containsKey(iv)) {
    cmnt.ParentId = importIdToLeadIdMap.get(iv);
}

By following these steps, you should be able to optimize your code and reduce the number of SOQL queries, which should resolve the Too many SOQL queries error. Remember that Salesforce imposes limits on the number of queries you can perform, so it's essential to design your code efficiently to stay within those limits.

Hope this will be helpful.
Thanks!
Stephen StoelingaStephen Stoelinga
The "Too Many SOQL Queries" error in Apex typically occurs when you are running multiple SOQL queries inside a loop. This is an anti-pattern in Apex development and should be avoided. In your code snippet, the issue is likely occurring because you are querying inside a loop:

```apex
for (Integer i = 1; i < csvFileLines.size(); i++) {
    // ...

    if (csvRecordData != null) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv)) {
            Lead ld = Database.query('SELECT id, import_id__c FROM User WHERE import_id__c = :iv');
            cmnt.ParentId = ld.Id;
        }

        cmntlist.add(cmnt);
    }
}
```

To solve the "Too Many SOQL Queries" error, you should follow best practices for bulkifying your code. In this context, bulkifying means performing the queries outside the loop, so you don't execute a query for each record in the loop. Here's one approach to refactor your code:

1. Create a Set to store the unique import IDs from the CSV data.

2. Loop through the CSV data to populate the Set with the import IDs.

3. Query the necessary data outside the loop, using the Set of import IDs, and store the results in a Map.

4. Use the Map to set the ParentId for each comment in the main loop.

Here's the updated code:
Securitas ePay (https://www.securitasepay.us/)
```apex
Set<String> importIds = new Set<String>();

// Populate the importIds Set with unique import IDs from the CSV data
for (Integer i = 1; i < csvFileLines.size(); i++) {
    // ...
    if (csvRecordData != null) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv)) {
            importIds.add(iv);
        }
        // ...
    }
}

// Query the Leads outside the loop and store the results in a Map
Map<String, Lead> leadsMap = new Map<String, Lead>();
for (Lead ld : [SELECT id, import_id__c FROM User WHERE import_id__c IN :importIds]) {
    leadsMap.put(ld.import_id__c, ld);
}

// Loop through the CSV data again to create FeedItems with ParentIds set from the Map
for (Integer i = 1; i < csvFileLines.size(); i++) {
    // ...
    if (csvRecordData != null) {
        String iv = csvRecordData[1];
        if (!String.isEmpty(iv)) {
            Lead ld = leadsMap.get(iv);
            if (ld != null) {
                cmnt.ParentId = ld.Id;
            }
        }
        // ...
        cmntlist.add(cmnt);
    }
}
```

By bulkifying the code and performing the query outside the loop, you can reduce the number of SOQL queries and avoid the "Too Many SOQL Queries" error. This approach will improve the performance and efficiency of your code, especially when dealing with large datasets.