contents
Documentation Version
Summer '15 (API version 34.0)
Language
English
  • Summer '15 (API version 34.0) 34.0
  • Spring '15 (API version 33.0) 33.0
  • Winter '15 (API version 32.0) 32.0
  • Summer '14 (API version 31.0) 31.0
  • Spring '14 (API version 30.0) 30.0
  • Winter '14 (API version 29.0) 29.0
  • English
  • Japanese

queryMore()

Retrieves the next batch of objects from a query().

Syntax

QueryResult = connection.queryMore( QueryLocator  QueryLocator);

Usage

Use this call to process query() calls that retrieve a large number of records (by default, more than 500) in the result set. The query() call retrieves the first 500 records and creates a server-side cursor that is represented in the queryLocator object. The queryMore() call processes subsequent records in up to 500-record chunks, resets the server-side cursor, and returns a newly generated QueryLocator. To iterate through records in the result set, you generally call queryMore() repeatedly until all records in the result set have been processed (the Done flag is true). You can change the maximum number of records returned to up to 2,000. See Change the Batch Size in Queries in the Salesforce SOQL and SOSL Reference Guide for more information.

You can't use queryMore() if a query includes a GROUP BY clause. See GROUP BY and queryMore() in the Salesforce SOQL and SOSL Reference Guide for more information.

Note

Note

A queryMore()call on a parent object invalidates all child cursors in the previous result set. If you need the results from the child, you must use queryMore() on those results before using queryMore() on the parent results.

When querying external objects, Lightning Connect accesses the external data in real time via Web service callouts. Each queryMore() call results in a Web service callout. The batch boundaries and page sizes depend on your adapter and how you set up the external data source.

We recommend the following:
  • When possible, avoid paging by filtering your queries of external objects to return fewer rows than the batch size, which by default is 500 rows. Remember, obtaining each batch requires a queryMore() call, which results in a Web service callout.
  • If the external data frequently changes, avoid using queryMore() calls. If the external data is modified between queryMore() calls, you can get an unexpected QueryResult.

If the primary or “driving” object for a SELECT statement is an external object, queryMore() supports only that primary object and doesn’t support subqueries.

By default, the OData 2.0 adapter for Lightning Connect uses client-driven paging. Specifically, the OData 2.0 adapter converts each queryMore() call into an OData query that uses the $skip and $top system query options to specify the batch boundary and page size. These options are similar to using LIMIT and OFFSET clauses to page through a result set. If you enable server-driven paging on an external data source, the external system determines the page sizes and batch boundaries. Also, the external system ignores any batch boundaries or page sizes that are specified in queries.

Sample Code—Java

This sample executes a query that fetches the first names and last names of all contacts. It calls query() with the query string to get the first batch of records. It then calls queryMore() in a loop to get subsequent batches of records until no records are returned. It writes the first and last names of the contacts queried to the console.

public void queryRecords() {
   QueryResult qResult = null;
   try {
      String soqlQuery = "SELECT FirstName, LastName FROM Contact";
      qResult = connection.query(soqlQuery);
      boolean done = false;
      if (qResult.getSize() > 0) {
         System.out.println("Logged-in user can see a total of "
            + qResult.getSize() + " contact records.");
         while (!done) {
            SObject[] records = qResult.getRecords();
            for (int i = 0; i < records.length; ++i) {
               Contact con = (Contact) records[i];
               String fName = con.getFirstName();
               String lName = con.getLastName();
               if (fName == null) {
                  System.out.println("Contact " + (i + 1) + ": " + lName);
               } else {
                  System.out.println("Contact " + (i + 1) + ": " + fName
                        + " " + lName);
               }
            }
            if (qResult.isDone()) {
               done = true;
            } else {
               qResult = connection.queryMore(qResult.getQueryLocator());
            }
         }
      } else {
         System.out.println("No records found.");
      }
      System.out.println("\nQuery succesfully executed.");
   } catch (ConnectionException ce) {
      ce.printStackTrace();
   }
}

Sample Code—C#

This sample executes a query that fetches the first names and last names of all contacts. It calls query() with the query string to get the first batch of records. It then calls queryMore() in a loop to get subsequent batches of records until no records are returned. It writes the first and last names of the contacts queried to the console.

public void queryRecords()
{
   QueryResult qResult = null;
   try
   {
      String soqlQuery = "SELECT FirstName, LastName FROM Contact";
      qResult = binding.query(soqlQuery);
      Boolean done = false;
      if (qResult.size > 0)
      {
         Console.WriteLine("Logged-in user can see a total of "
            + qResult.size + " contact records.");
         while (!done)
         {
            sObject[] records = qResult.records;
            for (int i = 0; i < records.Length; ++i)
            {
               Contact con = (Contact)records[i];
               String fName = con.FirstName;
               String lName = con.LastName;
               if (fName == null)
               {
                  Console.WriteLine("Contact " + (i + 1) + ": " + lName);
               }
               else
               {
                  Console.WriteLine("Contact " + (i + 1) + ": " + fName
                        + " " + lName);
               }
            }
            if (qResult.done)
            {
               done = true;
            }
            else
            {
               qResult = binding.queryMore(qResult.queryLocator);
            }
         }
      }
      else
      {
         Console.WriteLine("No records found.");
      }
      Console.WriteLine("\nQuery succesfully executed.");
   }
   catch (SoapException e)
   {
      Console.WriteLine("An unexpected error has occurred: " +
                                 e.Message + "\n" + e.StackTrace);
   }
}

Arguments

Name Type Description
queryLocator QueryLocator Represents the server-side cursor that tracks the current processing location in the query result set.

Response

QueryResult