I ran into the CPU time limit exceeded error when processing the results of a SOQL query in a for loop. I tried several alternatives and nothing seems to help. Any help is greatly appreciated.
Here is my code.
private Messaging.EmailFileAttachment getLocationsAttachment(){
//Construct the table header in CSV format.
string finalstr = Email.PrepareRecordStringForCSVAttachment(new string[] {'NAME','ID','ACCOUNT__R.NAME','ACCOUNT__C','STREET_AADDRESS__C','CITY__C','STATE__C','ZIP__C'});
for(Location__C l: [Select Name, Id, Account__r.Name, Account__c, Street_Address__c, City__c, State__c, ZIP__c FROM Location__c])
{
//Construct each row of the SOQL result set in CSV format.
string recordstr = Email.PrepareRecordStringForCSVAttachment(new object[]{l.Name, l.Id, l.Account__r.Name, l.Account__c, l.Street_Address__c, l.City__c, l.State__c, l.ZIP__c});
finalstr += recordstr;
}
return Email.ConvertToEmailAttachment(finalstr, 'Locations.csv');
}
public static Messaging.EmailFileAttachment ConvertToEmailAttachment(string attachmentContents, string attachmentName){
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
blob csvBlob = Blob.valueOf(attachmentContents);
attachment.setFileName(attachmentName);
attachment.setBody(csvBlob);
return attachment;
}
The number of records returned by the soql is 26,716 (Not too many).
I tried got rid of the "ConvertToEmailAttachment" function and made the code inline thinking it is probably spending too much time updating the stack during the function calls. However that did not change anything.
I also tried to use the for loop syntax to process batches of records from SOQL, that did not help either. Here is the code.
private Messaging.EmailFileAttachment getLocationsAttachment(){
//Construct the table header in CSV format.
string finalstr = Email.PrepareRecordStringForCSVAttachment(new string[] {'NAME','ID','ACCOUNT__R.NAME','ACCOUNT__C','STREET_AADDRESS__C','CITY__C','STATE__C','ZIP__C'});
for(List<Location__C> locs: [Select Name, Id, Account__r.Name, Account__c, Street_Address__c, City__c, State__c, ZIP__c FROM Location__c])
{
for(Location__C l: locs)
{
//Construct each row of the SOQL result set in CSV format.
string recordstr = Email.PrepareRecordStringForCSVAttachment(new object[]{l.Name, l.Id, l.Account__r.Name, l.Account__c, l.Street_Address__c, l.City__c, l.State__c, l.ZIP__c});
finalstr += recordstr;
}
}
return Email.ConvertToEmailAttachment(finalstr, 'Locations.csv');
}
My apologies, i thought i provided the code for generating the string. Here it is.
public static string PrepareRecordStringForCSVAttachment(object[] columnValues){
string recordString = '"';
integer colValsCount = columnValues.size();
for(integer i = 0; i<colValsCount - 1; i++)
{
recordString += columnValues[i] + '","';
}
recordString += columnValues[colValsCount - 1] + '"\r\n';
return recordString.replace('null', '');
}
public static string PrepareRecordStringForCSVAttachment(object[] columnValues){ string recordString = '"'; integer colValsCount = columnValues.size(); for(integer i = 0; i<colValsCount - 1; i++) { recordString += columnValues[i] + '","'; } recordString += columnValues[colValsCount - 1] + '"\r\n'; return recordString.replace('null', ''); }