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
ManvithaManvitha 

Unexpected token : "FROM" error

Hi All,
 I have created the batch class to create the custom records(fieldusage count object ) for each field of the passing object but gettig error 
can someone help here 
public class FieldUsageBatch implements Database.Batchable<sObject> {
public String objectName;

public FieldUsageBatch(String objName) {
objectName = objName;
}

public Database.QueryLocator start(Database.BatchableContext bc) {
String queryString = 'SELECT ';
Map<String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap();
List<String> customFieldNames = new List<String>();
for (String fieldName : fieldMap.keySet()) {
Schema.DescribeFieldResult fieldDescribe = fieldMap.get(fieldName).getDescribe();
if (fieldDescribe.isCustom()) {
customFieldNames.add(fieldName);
}
}
queryString += String.join(customFieldNames, ', ') + ' FROM ' + objectName;

return Database.getQueryLocator(queryString);
}

public void execute(Database.BatchableContext bc, List<sObject> scope) {
Map<String, Integer> fieldUsageMap = new Map<String, Integer>();
String objectFieldName = objectName + '.';

String aggregateQuery = 'SELECT ';
for (String fieldName : fieldUsageMap.keySet()) {
aggregateQuery += fieldName + ', COUNT(Id) countField' + fieldName + ' ';
}
aggregateQuery += 'FROM ' + objectName + ' GROUP BY ';
for (String fieldName : fieldUsageMap.keySet()) {
aggregateQuery += fieldName + ', ';
}
aggregateQuery += 'Id';

List<AggregateResult> results = Database.query(aggregateQuery);
for (AggregateResult result : results) {
for (String fieldName : fieldUsageMap.keySet()) {
Integer count = Integer.valueOf(result.get('countField' + fieldName));
String fieldValue = String.valueOf(result.get(fieldName));
if (fieldValue != null && count > 0) {
if (!fieldUsageMap.containsKey(fieldName)) {
fieldUsageMap.put(fieldName, count);
} else {
fieldUsageMap.put(fieldName, fieldUsageMap.get(fieldName) + count);
}
}
}
}

List<Field_Usage_Count__c> fieldUsageList = new List<Field_Usage_Count__c>();
for (String fieldName : fieldUsageMap.keySet()) {
Field_Usage_Count__c fieldUsage = new Field_Usage_Count__c(
External_Object_ID__c = objectName + '_' + fieldName, // Use an External Id field for upsert
Object_Name__c = objectName,
Field_Name__c = fieldName,
Count__c = fieldUsageMap.get(fieldName)
);
fieldUsageList.add(fieldUsage);
}

if (!fieldUsageList.isEmpty()) {
upsert fieldUsageList External_Object_ID__c; 
}
}

public void finish(Database.BatchableContext bc) {

}
}
Thank you in advance
SubratSubrat (Salesforce Developers) 
Hello ,

The error "Unexpected token: 'FROM'" is occurring because you have not added a space after the comma in the aggregateQuery string concatenation. The issue is in the execute method where you are building the aggregate query. You need to add a space after each comma in the query string to separate the fields correctly.

Here's the corrected execute method:
public void execute(Database.BatchableContext bc, List<sObject> scope) {
    Map<String, Integer> fieldUsageMap = new Map<String, Integer>();
    String objectFieldName = objectName + '.';

    String aggregateQuery = 'SELECT ';
    for (String fieldName : fieldUsageMap.keySet()) {
        aggregateQuery += fieldName + ', COUNT(Id) countField' + fieldName + ', ';
    }
    aggregateQuery += 'FROM ' + objectName + ' GROUP BY ';
    for (String fieldName : fieldUsageMap.keySet()) {
        aggregateQuery += fieldName + ', ';
    }
    aggregateQuery += 'Id';

    // Rest of your code remains unchanged
}
By adding spaces after each comma, the aggregateQuery string will be constructed correctly, and the error should be resolved. Additionally, make sure that the rest of your code, including the batch invocation and object setup, is set up correctly to avoid any other issues.

Hope this helps !
Thank you.