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
Muhammad MoneebMuhammad Moneeb 

Too Many SOQL (Checking OpportunityLineItem)

Hi guys ! i am going through every opportunity to copy records from another object  Here is my code 
List<OpportunityLineItem> result = new List<OpportunityLineItem>();
            List<PricebookEntry> pbe  = [SELECT Id, Product2Id, IsActive FROM PricebookEntry WHERE Product2Id IN :ProductIds];
               
                for (Opportunity op : opps){
                List<OpportunityLineItem> oli = [SELECT OpportunityId FROM OpportunityLineItem WHERE OpportunityId =: op.Id];
                   if(oli.size() == 0){
                     for(Sales_Order__c s :so){
                      	for(PricebookEntry pbee : pbe){
                     		for(SalesLine__c SL : productIdToSLineMap.get(pbee.Product2Id)){
                         		if(op.Id == s.Quote__c && SL.Sales_Order__c == s.Id){
                                    result.add (new OpportunityLineItem(
                                    OpportunityId = SL.Opportunity_Id__c,
                                    PricebookEntryId = pbee.Id,
                                    Quantity = SL.Quantity__c > 0 ? SL.Quantity__c : 1,
                                    UnitPrice =(SL.Quantity__c > 0 ? (SL.Amount__c > 0 ? SL.Amount__c/SL.Quantity__c : 0) : (SL.Amount__c > 0 ? SL.Amount__c : 0)))) ;
                          }
                        }
                      }
                   }
                   }else{
                       system.debug('OpportunityLineItem Exists');
                   }
             }
         insert result;

This gives too many soql error because i am checking if there are opportunitylineitems in opportunity in a loop is there a way to do this without querying in a loop  any help would be appreciated
Best Answer chosen by Muhammad Moneeb
jackzhufengsfdcjackzhufengsfdc
@Muhammad, Before your for loop, you should have codes like this:

Map<Id,List<OpportunityLineItem>> opp2opplineitems = [SELECT ID,NAME,(SELECT Id,OpportunityId FROM OpportunityLineItems) FROM OPPORTUNITY];

Then in loop, you can get opportunitylineitem list by opp2opplineitmes.get(opp.id);

All Answers

James LoghryJames Loghry
You're looping inside of a for loop.  If you have more than 100 opportunities in your "opps" list, then this will throw a SOQL exception.  Instead, loop through the opportunities first, and then construct a set of opportunity ids.  Change your SOQL to use
 
[SELECT OpportunityId FROM OpportunityLineItem WHERE OpportunityId in :oppIds]

Then, you'll likely need to refactor your logic a bit to conicide with "bulkifying" your class too.

 
Muhammad MoneebMuhammad Moneeb
@james if i use this query then how can i check for which opportunity there are opportunitylineitem or not i mean what code i will use in my loop 
Muhammad MoneebMuhammad Moneeb
i have to check before inserting a new opportunity line 
jackzhufengsfdcjackzhufengsfdc
@Muhammad, Before your for loop, you should have codes like this:

Map<Id,List<OpportunityLineItem>> opp2opplineitems = [SELECT ID,NAME,(SELECT Id,OpportunityId FROM OpportunityLineItems) FROM OPPORTUNITY];

Then in loop, you can get opportunitylineitem list by opp2opplineitmes.get(opp.id);
This was selected as the best answer