We all might have come across scenarios where we want to query for all the fields of an object. In SQL we use the symbol * to fetch all the fields, but unfortunately we do not have any such in SOQL. SF recently came up with amazing new feature in Spring'21 where all the fields belonging to a single sObject can be queried.
We can now use the below keywords in our SOQL.
- FIELDS(ALL) - Fetches all(including standard and custom) the fields of object.
- FIELDS(STANDARD) - This fetches only the standard fields of the object.
- FIELDS(Custom) - This fetches only the custom fields of the object.
For using the above Keywords, the pre-requisite is "LIMIT" keyword should be used with utmost value of "200". This means that not more than 200 records can be fetched if any of the above mentioned keywords are present in the SOQL. And also is not supported with an unbounded set of fields in this API
//Below query will fetch all the fields of the Account Object
SELECT FIELDS(ALL) FROM Account LIMIT 200
//Below query will fetch only the Standard fields of the Account Object
SELECT FIELDS(STANDARD) FROM Account LIMIT 200
//Below query will fetch only the custom fields of the Account Object
SELECT FIELDS(CUSTOM) FROM Account LIMIT 200
Source : https://developer.salesforce.com/blogs/2021/01/new-soql-fields-function-is-ga
It is undoubtedly a wonderful feature but with the limitation of not fetching more than 200 records and not making it completely available in apex, it could not solve our purpose in all the scenarios.
To overcome this, let us make use of Dynamic SOQL to get all the fields of the record. To make this generic enough, let's create a new static method which accepts object Name as String. With the received objectName it will return a SOQL Query(String) that includes all the fields
public class Utils { public static String prepareSOQL(String sobjectName){ String strSOQL = 'SELECT '; Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(sobjectName.toLowerCase()).getDescribe().Fields.getMap(); for (Schema.SObjectField ft : fMap.values()){ Schema.DescribeFieldResult fd = ft.getDescribe(); if (fd.isUpdateable()){ // add field only if it is accessable strSOQL += fd.getName()+','; } } strSOQL = strSOQL.removeEnd(','); strSOQL += ' FROM '+sobjectName; return strSOQL; } }
The above method accepts a string (objectName) and returns a SOQL Query of type string which includes all the fields and this can be invoked from any place when needed
//lstAcc will hold all the records with all the fields
String strSOQL = Utils.prepareSOQL('Account');
List<Account> lstAcc = Database.query(strSOQL);
Yes, you read it right. We all tend to use Maps and have them part of our SOQL query. But map.keyset() in a dynamic SOQL Query will not fetch the desired result. You need to assign the map.keyset() to another set variable and use set in your SOQL. It is because variables / collections can be used in dynamic SOQL, but not the methods.
Hope you find it interesting. Thank you for visiting and feedback is much appreciated!!!
"....Bazingaa..."
Fantastic
ReplyDeleteThank you Saurabh.
DeleteI would seriously question whether it is ever necessary to query for more than 200 fields. This has to be such a very special scenario where such a thing would be needed and it seems this leads developers to use this even when that is not needed. Seems like a dangerous thing to utilize, imho.
ReplyDeleteLIMIT 200 applies for the records not for the fields..
DeleteIt is very common for an object to hold more than 200 records and given provision of SF will fail in such scenario.
The alternative method mentioned in this post will help in such scenario of preparing the Soql dynamically
very helpful
ReplyDelete