Find your content:

Search form

You are here

Can I tell if I queried a field?

 
Share

I have some code that queries some fields from an object. I then use the schema to loop over all of the fields of an object. Is there a way, while I'm looping through the schema to tell if I had queried for a field before I try to use the sobject.get method?

List<Account> accs = [SELECT RecordTypeId, Name FROM Account];

List<Schema.SObjectField> fields = Schema.SOBjectType.Account.fields.getMap().values();
for (Account acc: accs)
{
  for (Schema.SObjectField field: fields)
  {
    //This will fail if I did not query for the field
    Object sField = acc.get(field.getDescribe().getName());
  }
}

Attribution to: dphil

Possible Suggestion/Solution #1

One way to do this would be to convert the sobject to JSON and use the parser.

Contact myContact = [SeLect Id, Name FROM Contact LIMIT 1];
String contactJson = JSON.serialize(myContact);
JSONParser parser = JSON.createParser(contactJson);

Set<String> queriedFields = new Set<String>();

JSONToken token = parser.nextToken();
token = parser.nextToken(); 
while(parser.hasCurrentToken() ){
  String text = parser.getText();
  if(JSONToken.START_OBJECT == token){
    parser.skipChildren();
    token = parser.nextToken();
  }
  if('attributes' != text && JSONToken.FIELD_NAME == token)
      queriedFields.add(parser.getText());

   token = parser.nextToken();
}

for(String field : queriedFields){
    System.debug(field);
}

Attribution to: Justin Julicher

Possible Suggestion/Solution #2

I just came up with an idea:

try
{
  Object sfield = audit.get(fromName);
} catch (Exception e)
{
  continue;
}

Does anyone have a better idea without catching it if there is an error though?


Attribution to: dphil

Possible Suggestion/Solution #3

the only other way to do this besides a try/catch is to write your query dynamically so that you get every field.

Example:

string queryString = 'SELECT ';
for(string field:Schema.SOBjectType.Account.fields.getMap().values())
    queryString += field+',';
queryString = queryString.removeEnd(',') + ' FROM Account';

if(stillNeedsToAddToQuery) // add WHERE, LIMIT, etc. stuff if need be
    // stuff

list<Account> accountList = (list<Account>)database.query(queryString); 
// database.query() returns  list<sObject>, so I like to cast my result

See my answer here for some Utility Methods + Test Code: Can a SOQL query selecting all columns be generated at runtime?


Update

Both @dphil and my answers are equivalent but opposite in a sense when you are dealing with "general" query results:

  • You either filter the input fields for the query (My method gives you all of the fields, and then you can create another method to filter for the appropriate situation.)
  • try/catch whatever the "general" query result is. (And there are clever things that can be done in the catch part too such as break the loop, write another query adding the missing field, and try again with the re-queried results.)

Attribution to: Scott Pelak

Possible Suggestion/Solution #4

Use Map<String, Object> getPopulatedFieldsAsMap() method on the sobject. It gives you a map of fields and values that got queried.

Please refer to this release notes for more information: (http://releasenotes.docs.salesforce.com/en-us/summer16/release-notes/rn_apex_sobject_getmap.htm)


Attribution to: psun
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/33578

My Block Status

My Block Content