My code is

 myOutput = SELECT location__c, level__c, group__c, count__c from resource__c
 public sobject[] data = Database.query(myOutput);

myOutput is an user input value, based on this query I have to list the fields to a selectList. Here in this case, I have to show the list of fields location_c, level_c, group_c, count_c. Please help me to do this in apex.

The below code will display all the fields from the object resource__c, but I want only the fields in the query entered by the user.

Map<String, Schema.SObjectField> schemaFieldMap = Schema.SObjectType.resource__c.fields.getMap();
    for (String fieldName: schemaFieldMap.keySet()) {
        options.add(new SelectOption(fieldName, fieldName));  
  • I couldn't understand what do you mean by "I want only the fields in the query entered by the user." Jan 16, 2014 at 5:47
  • myOutput is an input field where I am getting value (Query) from the user, here in this example user entered the query "SELECT location__c, level__c, group__c, count__c from resource__c". My requirement is to list the fields in this query to an selectList.
    – staticraj
    Jan 16, 2014 at 5:54
  • better parse the input query(myOutput ) Jan 16, 2014 at 5:57

2 Answers 2


UPDATED: Following comment request see below for related fields

There is no method on the SObject class that can be used to determine if a field has been queried. I would add this to the 'hasError' method request as well btw!

In the meantime I can see two options...

Catching SObjectExceptions

You can catch the exception that is generated from attempting to reference a field that has not been queried, thus its possible to compile a list of queried fields by catching the exception. The following example shows the idea for immediate fields on the Account record, it can be extended for relationships also, by adapting it to reference the child relationships returned by Apex Describe.

Account account = [select Id, AnnualRevenue, Website from Account limit 1];
Map<String, Schema.SObjectField> schemaFieldMap = Schema.SObjectType.Account.fields.getMap();
Map<String, Object> queriedFieldValues = new Map<String, Object>();
for (String fieldName: schemaFieldMap.keySet()) {
    try { 
        queriedFieldValues.put(fieldName, account.get(fieldName)); 
    } catch (SObjectException e)    { 
        // Intentional capture 

The following outputs...

06:40:47.071 (71864669)|USER_DEBUG|[11]|DEBUG|{annualrevenue=30000000, id=001G000000qdARPIA2, website=www.genepoint.com}

Using JSON Serialisation

The JSON serialisation support only emits populated values, you can leverage this by serialising then immediatly deserialising the JSON. Using the untyped JSON deserialize method you can get a map of field values.

Account account = [select Id, AnnualRevenue, Website from Account limit 1];
Map<String, Object> queriedFieldValues = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(account));

This outputs the following...

07:03:46.072 (72023287)|USER_DEBUG|[3]|DEBUG|{AnnualRevenue=30000000, Id=001G000000qdARPIA2, Website=www.genepoint.com, attributes={type=Account, url=/services/data/v29.0/sobjects/Account/001G000000qdARPIA2}}


Neither option is the direct approach we would like, but on balance I'd say perhaps the second might be more efficient, though i don't know for sure, raising exceptions can be quite expensive in languages like Java as a stacktrace and other debug info needs to be resovled. So if you scale the former solution to more records, children etc it will likely not win compared to the JSON approach. Though feel free to make your own choice and tests.

Update to Show Supported for Querying Related Fields.

Further to the query in the comments regarding accessing related field information, I have revised the example code as follows to included the related fields queried.

public with sharing class QueryQueriedFields 
    public static void demo()
        Account account = [select Id, AnnualRevenue, Website, Owner.Username from Account limit 1];
        Map<String, Object> queriedFieldValues = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(account));
        dumpFields('', queriedFieldValues);

    public static void dumpFields(String relatedField, Map<String, Object> queriedFieldValues)
        for(String queriedFieldName : queriedFieldValues.keySet())
            // Skip this information, its not a field
            // Check if the queried value represents a related field reference?
            Object queriedFieldValue = queriedFieldValues.get(queriedFieldName);
            if(queriedFieldValue instanceof Map<String,Object>)
                dumpFields(queriedFieldName + '.', (Map<String, Object>) queriedFieldValue);
                System.debug(relatedField + queriedFieldName + ' = ' + queriedFieldValue);

This now outputs...

02:31:39.104 (104629544)|USER_DEBUG|[22]|DEBUG|Owner.Username = [email protected]

02:31:39.104 (104734352)|USER_DEBUG|[22]|DEBUG|Website = www.genepoint.com

02:31:39.104 (104807836)|USER_DEBUG|[22]|DEBUG|Id = 001G000000qdARPIA2

In order to understand how this works, you need to see the JSON structure, as you can see it is structured with the related fields in a substructure. In order to support related references beyond the first level, a recursive approach was taken.

        [email protected],
  • Now, I'm using the below code to get the fields String[] jsonFields = new List<String>(); for (String qFields: queriedFieldValues.keySet()) { if (! (qFields.equalsIgnoreCase('Id') || qFields.equalsIgnoreCase('attributes'))){ jsonFields.add(qFields); } } but for the below query, I'm getting values as manager__c, resource__r & resource__c SELECT manager__c, resource__r.group__c, resource__r.location__c FROM management__c ORDER BY resource__r.location__c Your help is appreciated.
    – staticraj
    Jan 17, 2014 at 9:40
  • Yes sure when I get a chance later today I'll update to show how to reference related fields via the maps returned by the JSON calls. Jan 17, 2014 at 15:29
  • Ok I've updated my answer with a revised and improved approach, this should do what you need! :-) Jan 18, 2014 at 2:36
  • Thanks for your detailed explanation and solution. I'm struck in the below query, JSON created array of objects for field - records. Query: SELECT group__c, (SELECT manager__c FROM managements__r) FROM resource__c USER_DEBUG|[77]|DEBUG|{Group__c=Airline & Platforms, Id=a07i00000087ZJjAAM, Managements__r={done=true, records=({Id=a09i0000005tAaOAAU, Manager__c=Joseph, Resource__c=a07i00000087ZJjAAM, attributes={type=Management__c, url=/a09i0000005tAaOAAU}}), totalSize=1}, attributes={type=Resource__c, url=//sobjects/Resource__c/a07i00000087ZJjAAM}} Any Solution?
    – staticraj
    Jan 20, 2014 at 13:05
  • Ah a subselect, we could be going quite a while adapting and improving this code i feel. The general idea though is your parsing in a generic way the JSON serialised form. Take the output from JSON.serialize and run it through JSONLint web site to make it readable, the adapt the code I've given you. You may have to figure some other data structure in memory to reflect subselects and again be recursive as the subselect query can use many of the features of the outer query. If your still struggling might have to move this to another question... Jan 20, 2014 at 23:09

One liners:


Or for dynamic queries:

String.join(new List<String>(SObject__c.sObjectType.getDescribe().fields.getMap().keySet()), ',');

You must log in to answer this question.

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