Howto wildcard SELECT * to query all fields of objects in APEX?

Update: Spring '21 Release (API v51+) adds new SOQL FIELDS function can select all fields of an object. Refer to documentation

Knowing that new FIELDS function must have a LIMIT of at most 200, when used with ALL or CUSTOM keyword, the workaround below can still be useful.


There is no way to Select * with SOQL.

You can however work-around this limitation by using dynamic SOQL and describe methods to get all of the fields on the object. This is described in detail in this post by Cory Cowgill:

Building Dynamic SOQL - Select All Query


I created some helper classes for this. You can find them here. There are 3 classes: xt, xs and xr. They contain also some other tools I couldn't separate for this answer, but the method you need is xs.query() in xs.cls. To get all straight into your Org, just use the "Deploy to Salesforce" link.

The usage is very simple. Just go somewhere to Execute Anonymous (e.g. in Eclipse), put ALL log-levels to WARN (to make the output readable) and try:

xt.log(xs.query('SELECT * FROM Opportunity LIMIT 2'));

or:

xt.log(xs.query('SELECT *, CreatedBy.* FROM Opportunity LIMIT 2'));

or even:

xt.log(xs.query('SELECT *, CreatedBy.*, Account.Owner.* FROM Opportunity LIMIT 2'));

to exclude some fields use:

xt.log(xs.query('SELECT *.not(Name|Probability) FROM Opportunity LIMIT 2')); 

The results should come close to your expectations. If you just want to compose the soql-string, you can use xs.soql(). xt.log() is just for demonstration purpose and very similar to system.debug().

Hints:

  • Supports relations for standard (Account.*) and custom fields (YourFile__r.*).
  • Supports distant relations like Whatever__r.WhateverElse__r.AndMore__r.*.
  • Queries work in non-prefixed and prefixed Orgs (Managed Packages).
  • The included tests are very poor and only to get some coverage.
  • There is a platform-limitation of the maximum length of the soql-string (about 20 000 characters). So if you use SELECT * ... on objects with too many custom fields, you will run into this limit.
  • To pass security reviews, you may have to change without sharing to with sharing in xs.cls.
  • Take care on FLS if you go without sharing.
  • If you use subselects, you need to do something like xt.log(database.query(xs.soql('SELECT* from Whatever') + ' WHERE WhateverField IN (yourSubQuery) '));

I suggest that rather than relying on some utility class, you become familiar with the platform's APIs so you can compose the appropriate solution each time you want to query all the fields, particularly if your queries are simple and only involve one object. Whoever gets to maintain the code in the future will thank you for keeping things simple and direct too.

Its as simple as this:

List<String> fields = new List<String>(Contact.SObjectType.getDescribe().fields.getMap().keySet());
String soql = ''
        + ' select ' + String.join(fields, ',')
        + ' from Contact'
        + ' where ...';
for (Contact c : (Contact[]) Database.query(soql)) {
    // ...
}

and the only part I would consider moving into a helper method would be the creation of the fields list.