5

When I update records in SFDC using dataloader, it executes my trigger and I'm getting a System.LimitException: Too many SOQL queries: 101. I am now changing my trigger so that I don't make any SOQL calls in the FOR loop. Problem is, how can I get the oldMap and NewMap of the Opportunity outside the for loop? Because the for loop is creating the variable "opp" which I need to reference to get the old map. How can i do this outside the for loop? I've tried looking for syntax but haven't found anything. Thanks in advance for the help.

trigger TestTrigger on Opportunity (before update) {
    Opportunity oldOpportunity = Trigger.oldMap.get(opp.ID);
    for(Opportunity opp : Trigger.new){
       ...
       oppOwnerId = [SELECT Id FROM User WHERE Id=:oldOpportunity.OwnerId limit 1];
       ...
    }
}

1 Answer 1

9

To access a Map (as in oldMap), you will need to access by Id. If it is just the old Opportunity Owner ID you are after, you can simply access it as - no need to perform the query:

trigger TestTrigger on Opportunity (before update) {
    for(Opportunity opp : Trigger.new){
       Opportunity oldOpportunity = Trigger.oldMap.get(opp.ID);
       oppOwnerId = oldOpportunity.OwnerId;
       ...
    }
}

However, i suspect you are not and that you do need to perform the query to retrieve some other information, in which case you are thinking about this the wrong way. You need to 'bulkify' your Trigger.

What you will have to do instead of what you are suggesting is refactor your trigger a little. You should first collect a set of OwnerIds from the 'old' collection, for example:

Set<Id> ownerIds = new Set<Id>();
for( Opportunity opp : Trigger.old ) {
    ownerIds.add( opp.OwnerId );
}

Then, using that set, you should query all of the Users outside of the loop (i.e. once for all the OwnerIds) and create a Map for easy access, for example:

Map<Id,User>  userMap = new Map<Id,User> ( [ Select Id From user Where Id IN ownerIds ] );

Then, from within the Loop, you can access the User as you wish using the map:

for( Opportunity opp : Trigger.new ) {
    User oppOwnerId = userMap.get( Trigger.oldMap.get( opp.Id ).OwnerId );
}

This is a rather futile example because the code is only returning the User Id which you essentially have already anyway (in the oldMap).

2
  • this was basically what i was looking for, you got it bang on. Thanks so much.
    – user988
    Commented Nov 26, 2013 at 18:26
  • No problem, glad to be of assistance. Commented Nov 26, 2013 at 18:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .