1

I want to make use of getLimitQueryLocatorRows() before i use the below code and throw exception or custom error message accordingly. Is this possible?

SetCon = new ApexPages.StandardSetController(Database.getQueryLocator(query));
1

It looks like there's a typo in the current documentation for getLimitQueryLocatorRows(). It should say this returns an integer with the number of records that can be returned by the Database.getQueryLocator method. You use this method in conjunction with getQueryLocatorRows() which returns the actual number of records that have been returned by the Database.getQueryLocator method during a transaction.

At the start of a transaction, you'd execute the following lines:

integer rowsAvailable = Limits.getLimitQueryLocatorRows();
integer rowsReturned = Limits.getQueryLocatorRows(); 

rowsAvailable should return an integer with the number of rows available that can be returned by your query. rowsReturned should be zero since you've not run your locator query.

After running SetCon, you'd run the following lines of code:

integer rowsAvailable1 = Limits.getLimitQueryLocatorRows();
integer rowsReturned1 = Limits.getQueryLocatorRows(); 

rowsAvailable1 should be equal to rowsAvailable - rowsReturned1. If rowsReturned1 < rowsAvailable1 you won't want to run SetCon again until your Limits (rowsAvailable) which are usually part of a rolling 24 hour limit, have increased to above the value returned in rowsReturned1.

Without more context of how you intend to use your query locator code code (e.g. as part of chained batch or queueable, etc), it's difficult for me to give you a better answer to your question than this.

EDIT:

In response to comments - You're correct that instantiating a SetController from a query locator that returns more than 10,000 records will cause a LimitException. However, instantiating a StandardSetController with a list of more than 10,000 records doesn’t throw an exception, and instead truncates the records to the limit.

First, you may want to look at StandardSetController Methods in the Visualforce Developer Guide. You'll find a boolean method there getCompleteResult():

Indicates whether there are more records in the set than the maximum record limit. If this is false, there are more records than you can process using the list controller. The maximum record limit is 10,000 records.

So, if you assign a list of records, your setController will truncate them to 10,000 records if the list exceeds the limit and no exception will be thrown.

If you feel it's likely that you'll be exceeding the 10,000 record limit, you could potentially do a couple of different things. One would be something like this:

public class opportunityList2Con {
    // ApexPages.StandardSetController must be instantiated
    // for standard list controllers
    public ApexPages.StandardSetController setCon {


        get {
            if(setCon == null) {
                list<AggregateResult>oppCount = [SELECT Count FROM Opportunity];
                if(oppCount.Count < 10000){
                    setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                        [SELECT Name, CloseDate FROM Opportunity]));
                 }
            }
            return setCon;
        }
        set;
    }

    // Initialize setCon and return a list of records
    public List<Opportunity> getOpportunities() {
        return (List<Opportunity>) setCon.getRecords();
    }
}

Alternatively, you could potentially create a custom iterator like below and find a way to assign the results to your SetController:

Database.QueryLocator q = Database.getQueryLocator(
    [SELECT Name FROM Account LIMIT 10000]);
Database.QueryLocatorIterator it =  q.iterator();

I'll add that I successfully ran the code below as Anonymous Apex in my DE Org. Perhaps this might give another idea on an alternative approach to handling your concerns:

    list<Opportunity>OppList = [SELECT Name FROM Opportunity limit 1];
    ApexPages.StandardSetController setCon = new ApexPages.StandardSetController(OppList); 
    setCon = null;

        if(setCon == null) {
            integer oppCount = [SELECT Count() FROM Opportunity];
            if(oppCount < 10000){
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                        [SELECT Name, CloseDate FROM Opportunity]));
             }
        }

        system.debug(setCon.getCompleteResult());
  • Thanks for the detailed explanation. However if the query is returning more than 10000 records then SetCon will throw an exception and will never execute the following lines (rowsAvailable1, rowsReturned1 ). I just wanted to know how many rows my dynamic query is going to return before I use the query with SetCon to avoid this exception. – Kanikala May 8 '18 at 2:38

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.