function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Cable Guy.ax375Cable Guy.ax375 

insert using batch mode

How can I modify the following code so it can insert 200 records each time? I'm using API version 7.
 
Assume I already have a recordset of 50000 records from Oracle database.
 
public void updateEquipment(ID buildingID, String clliCode, String equipSpecType, String vendorName,
      String vendorPartNum, String materialCode, String vendorCommCode, String vendorIssueNum,
      String equipSpecID, String equipAcronym, String equipDesc, Double equipCount)
 
    {
      
     Equipment__c eq = new Equipment__c();
    
      eq.setBuilding__c(buildingID);
      eq.setCLLI_code__c(clliCode);
      eq.setEquipspec_Type__c(equipSpecType);
      eq.setVendor_Name__c(vendorName);
      eq.setVendor_Part_Number__c(vendorPartNum);
      eq.setMaterial_Code__c(materialCode);
      eq.setVendor_Comm_Code__c(vendorCommCode);
      eq.setVendor_Issue_Number__c(vendorIssueNum);
      eq.setEquipment_Spec_ID__c(equipSpecID);
      eq.setEquipment_Acronym__c(equipAcronym);
      eq.setDescription__c(equipDesc);
      eq.setQuantity__c(equipCount);
      eq.setName(equipSpecType);
    
    
      SObject[] sObjects = new SObject[1];
     
      sObjects[0] = eq;
        
      
      try {
       
       
       SaveResult[] saveResults = binding.create(sObjects);
    
     
        for (int i=0; i<saveResults.length; i++) {
         
          if (saveResults[i].isSuccess()) {
            
           Logger.log("updateEquipment() - " + saveResults[i].getId(),true);
            System.out.println("insert equipment " + saveResults[i].getId());
          }
          else {
               
           Logger.log("updateEquipment() - " + saveResults[i].getErrors()[i].getMessage(),true);
          }
         
        }
      } catch (InvalidSObjectFault e) {
       Logger.log("updateEquipment() - invalid object exception encountered:\n\n" + e.getMessage(),true);
    
      } catch (UnexpectedErrorFault e) {
       Logger.log("updateEquipment() - Unexpected error exception encountered:\n\n" + e.getMessage(),true);
     
      } catch (RemoteException e) {
       Logger.log("updateEquipment() - Remote exception encountered:\n\n" + e.getMessage(),true);
  
      }
      
    }
 
 
SuperfellSuperfell
I like to use an accumulator style pattern for this, IIRC, there's a detailed example in the force.com cookbook.
Cable Guy.ax375Cable Guy.ax375
i downloaded salesforce_platform_cookbook.pdf and searched on accumulator, didn't find any match. But I found the sample code of Batching Records for API Calls.
 
Basically I looped through the recordset and use each record to set the value of my object(in my case, it's Equipment). Then filled the array of SObject[] with each new object. Then pass the SObject[] and batch size to the create() call that I got from the sample code.
 
I have 2 issues regarding this approach: 1) it still takes long time to set the value of the object when you loop through my java recordset(in my case, set the Equipment value).
2) when I called create(SObject[] records, int batchSize), I got "invalid object exception encountered" error.
 
The following is the sudo code:
 
while (it.hasNext())
{
                                Equipment__c eq = new Equipment__c();
                           
                             eq.setBuilding__c(buildingID);
                             eq.setCLLI_code__c(clliCode);
                             eq.setEquipspec_Type__c(equipSpecType);
                             eq.setVendor_Name__c(vendorName);
                             eq.setVendor_Part_Number__c(vendorPartNum);
                             eq.setMaterial_Code__c(materialCode);
 
                             sObjects[j] = eq;
                              j++;
 }
sfdc.create(sObjects, 200);
 
The following is the code I got from the cookbook regarding batching records for api call:
 
public SaveResult[] create(SObject[] records, int batchSize) throws InvalidSObjectFault, UnexpectedErrorFault, InvalidIdFault, RemoteException, ServiceException {
   if (batchSize > 200 || batchSize < 1)
    throw new IllegalArgumentException("batchSize must be between 1 and 200");
   return batch(records, batchSize, new CreateBatcher());
  }

  private SaveResult[] batch(SObject[] records, int batchSize, Batcher batchOperation) throws UnexpectedErrorFault, InvalidIdFault, LoginFault, RemoteException, ServiceException {
   if (records.length <= batchSize) {
    //checkLogin();
    return batchOperation.perform(records);
   }
   SaveResult[] saveResults = new SaveResult[records.length];
   SObject[] thisBatch = null;
   int pos = 0;
   while (pos < records.length) {
    int thisBatchSize = Math.min(batchSize, records.length - pos);
    if (thisBatch == null || thisBatch.length != thisBatchSize)
     thisBatch = new SObject[thisBatchSize];
    System.arraycopy(records, pos, thisBatch, 0, thisBatchSize);
    SaveResult [] batchResults = batch(thisBatch, thisBatchSize, batchOperation);
    System.arraycopy(batchResults, 0, saveResults, pos, thisBatchSize);
    pos += thisBatchSize;
   }
   return saveResults;
  }

  private abstract class Batcher {
   abstract SaveResult[] perform(SObject [] records) throws UnexpectedErrorFault, InvalidIdFault, LoginFault, RemoteException, ServiceException;
  }

  private class CreateBatcher extends Batcher {
   SaveResult [] perform(SObject [] records) throws UnexpectedErrorFault, InvalidIdFault, LoginFault, RemoteException, ServiceException {
    //checkLogin();
    return binding.create(records);
   }
  }

  private class UpdateBatcher extends Batcher {
   SaveResult [] perform(SObject [] records) throws UnexpectedErrorFault, InvalidIdFault, LoginFault, RemoteException, ServiceException {
    //checkLogin();
    return binding.update(records);
   }
  }
Cable Guy.ax375Cable Guy.ax375
The function create(sObjects, 200) works only when sObjects's length is equals or less than 200, which is exactly what I want. The problem is how can I set the sObjects 200 each time when I go through the loop of all the records from the Oracle database? 
 
While (Oracle_data_recordset.hasNext()) // loop through the 50,000 oracle database recordset
{
Equipment__c eq = new Equipment__c();
                           
                             eq.setBuilding__c(buildingID);
                             eq.setCLLI_code__c(clliCode);
                             eq.setEquipspec_Type__c(equipSpecType);
                             eq.setVendor_Name__c(vendorName);
                                           
                             sObjects[j] = eq;
j++
}
 
create(sObjects, 200);
 
-------------------------------------------------------
Question: how can I set 200 equipment objects to sObjects in one shot and pass it to create function? So basically I only need to call create function 250 times if I have 50,000 records retrieve from my Oracle database.