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 thecatch
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