9

I have written the below web service class to return record count. But it is returning the following message "System.LimitException: Too many query rows: 50001". How could I overcome this limit?

@RestResource(urlMapping='/count/*')
global with sharing class GetCount{
    @HttpGet
        global static String doCount() {
        RestRequest req = RestContext.request;        
        String objName = req.requestURI.split('/')[2];
        String whereClause = EncodingUtil.urlDecode(req.requestURI.split('/')[3],'UTF-8');        
        return database.countQuery('SELECT COUNT() FROM ' + objName + ' WHERE ' +  whereClause);
    }
}
5

There is a way to do it, but it isn't pretty. You can have your Apex call the REST API and then parse the JSON to get the count. This works in my org with 1.5 million cases.

@RestResource(urlMapping='/count/*')
global with sharing class GetCount{
    @HttpGet
        global static Integer doCount() {
            RestRequest restreq = RestContext.request;        
            String objName = restreq.requestURI.split('/')[2];

            HttpRequest req = new HttpRequest(); 
            req.setMethod('GET');
            req.setEndpoint('https://na12.salesforce.com/services/data/v30.0/query/?q=SELECT+COUNT(Id)+FROM+' + objName);
            req.setHeader('Authorization', 'Bearer '+ UserInfo.getSessionId());
            req.setTimeout(60000);        
            Http http = new Http();
            HTTPResponse res = http.send(req);

            Map<String, Object> response = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
            List<Object> records = (List<Object>) response.get('records');
            return (Integer) ((Map<String, Object>) records[0]).get('expr0');
        }

    }

To use this you have to add your org in the remote site settings. You also shouldn't hard code the org instance in the class.

| improve this answer | |
1

While not a perfect solution you could:

  1. Create a custom Setting to store the record count by objectName
  2. Populate the Initial values for all records either manually or by a batch class
  3. Write a trigger on insert or delete for each object to update the value for each record (Utility class maybe)
  4. In your rest request, return the custom setting value for the object name

Given the limitations of number of rows returned you can customize for only those objects where you think the value will exceed 50,000 and revert to this method (saves you writing triggers for all objects), for others you can do the query. Doing it this way for all objects will speed up the request though.

Just one solution if the functionality is really needed.

| improve this answer | |
  • See Daniel's post on doing this using APEX REST. Much easier solution to implement – Eric May 10 '14 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.