Print this page

Exception In a VF email template: Query is either selecting too many fields or the filter conditions are too complicated

Knowledge Article Number 000188549
Description Scenario- 
User has created a VF email template which displays too many fields.

Issue-
When the user uses this VF email template, the following exception is seen:
Query is either selecting too many fields or the filter conditions are too complicated
 
Resolution The SOQL limit cannot be increased in production.
Please refer to the following link:
https://help.salesforce.com/help/pdfs/en/salesforce_app_limits_cheatsheet.pdf

Following are the 2 workarounds:
1)  Update the API names on all the fields used in the VF email template and make them relatively small so that the SOQL statement size is under limits. 
Cons- Even after updating the API names, there is no guarantee that the SOQL statement limit will be under limit especially if there are too many cross object formula fields in the VF email template.

2) Use custom controllers in VF email template. 
In the custom controller, user should split the query in 2-3 parts and then merge their results in the VF email template. 
For instance- 
////////////////////////////////////////////////////////////////////////////////////// 
a) Custom controller class "findSmithAccounts" 
public class findSmithAccounts { 
	private final List<Account> accounts1, accounts2; 

	public findSmithAccounts() { 
	//splitting the query in query 1 and query 2 as follows-
		accounts1 = [select Name from Account where Name LIKE 'Smith_%']; //query 1

		accounts2= [select Type from Account where Name LIKE 'Smith_%']; //query 2 
	} 

	public List<Account> getSmithAccountsQuery1Fields() { 
		return accounts1; 
	} 

	public List<Account> getSmithAccountsQuery2Fields() { 
		return accounts2; 
	} 
}

 
////////////////////////////////////////////////////////////////////////////////////// 
b) Custom component named "smithAccounts":- 
<apex:component controller="findSmithAccounts" access="global"> 
	<apex:dataTable value="{!SmithAccountsQuery1Fields}" var="s_account1"> 
		<apex:column> 
			<apex:facet name="header">Account Name</apex:facet> 
			{!s_account1.Name} 
		</apex:column> 
	</apex:dataTable> 

	<apex:dataTable value="{!SmithAccountsQuery2Fields}" var="s_account2"> 
		<apex:column> 
			<apex:facet name="header">Account Type</apex:facet> 
			{!s_account2.Type} 
		</apex:column> 
	</apex:dataTable> 
</apex:component>

 
////////////////////////////////////////////////////////////////////////////////////// 
c) VF email template leveraging the custom controller via the component
<messaging:emailTemplate subject="XXX" recipientType="Contact" relatedToType="Opportunity"> 
	<messaging:htmlEmailBody> 
		<p>As you requested, here's a list of all our Smith accounts:</p> 
		<c:smithAccounts/> 
		<p>Hope this helps with the {!relatedToType}.</p> 
	</messaging:htmlEmailBody> 
</messaging:emailTemplate>

 
 
Documentation for VF email template using custom controller can be found here - 




promote demote