Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (5) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) Force.com tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Initialising Maps from Queries to Save Script Statements

Initialising Maps from Queries to Save Script Statements

Post by Ankit Arora (forceguru)  (2011-05-05)

Status: Unverified
Level: intermediate

Problem

You need to create a list of identifiers of records from a query, but want to save on governor limits and not iterate over the list.

Problem Description

While writing Apex code, it's useful to understand how to reduce the number of executed code statements so that you can stay within the governor limits. This recipe shows a best practice you can apply when you need a list of identifiers of records, generated from a query.

If you want to create a list of IDs from a query to process later, you may write something like this:

//Fetching all accounts
List<account> accObj = [select Id from account limit 50000] ;

//Creating set of all account Ids
List<id> accIds = new List<id>() ;

//Fetching Account ids
for(Account acc : accObj)
{
 accIds.add(acc.id) ;
}

Now if the query returns 50,000 records, this code will execute more than 50,000 code statements.

Solution

To avoid this you can simply initialize an Apex map with the query, and use it instead of creating a List. Here it is in action:

//Fetching all account in map
Map<id,account> aMap = new Map<id,account>([Select Id,Name from Account limit 50000]);

//Creating list of accounts
List<account> accList = aMap.values() ;

//Creating set of ids
Set<id> accIds = aMap.keySet() ;

This code uses only 3 script statements instead of 50,000.

Discussion

Note that if the query returns sObject as a return type, then you can still use this approach by typecasting the result:

//Your dynamic query
String accountDynamicQuery = 'select id from account limit 50000' ;

//Typecasting it to map
Map<id,account> mapAcc = new Map<id,account>((List<account>)Database.query(accountDynamicQuery));

Share

Recipe Activity - Please Log in to write a comment

I really wish these examples used proper case on object types.

by deckblad11082013  (2014-08-05)

On the issue of the cast from dynamic soql, I heard word that this may be fixed in the next release so you can use generic sObjects in the map constructor.

by Chris Peterson  (2012-03-09)

Nice tips. Thanks.

by sivarajan.d02202010  (2011-07-12)

I used this in one of my project in which I was expecting so many script statements due to iterations. This recipe saved me.

voted as verified by Amit Jain  (2011-05-31)

Very helpful while dealing with bulk data.

voted as verified by Shashikant Sharma  (2011-05-27)

 No we can not, only format available is Map<Id , SObject>.

by Ankit Arora (forceguru)  (2011-05-17)

can we create a map<String,contact>  where String is the email of the contact?

by siddharatha nagavarapu  (2011-05-16)

This recipe helps me, so I am verifying it.

voted as verified by DevendraNatani  (2011-05-06)

X

Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on Force.com. When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.