1

This problem is quite related to my first question in this link Get Data from batch iterable I have created a functionality that will upload data to salesforce object using csv. My problem at the moment is that, how will I get the first row of the csv when using batch process. I've tried to use the answer that i've marked as correct in the above link.This is the sample code I've created

public with sharing class DI_batchProcessor implements Database.batchable<String>, Database.Stateful {
  public String[] headings;

  public void execute(Database.BatchableContext batchableContext, List<String> scope) {
    if (headings == null) {
        headings = scope[0].split(',');
    }

    if(headings != null){
        // create the process of insertion here
    }
  }

  public void finish(Database.BatchableContext bc) {
  }

}

It is working well when I upload a correct data. But when I try to upload 220 records and some data inside the first iteration(from 0 -200 row) is invalid, the headings data will be renewed. Instead of row 0, the headings will get the 201 row. Am I missing something ? I've check my code and there is no part where I update my headings variable. Please help. Thank you..

1 Answer 1

0

You should isolate the header from execute process. See example below where we are using constructor instead of execute.

You may have to slightly change your iteration logic but it is feasible.

public with sharing class DI_batchProcessor implements Database.batchable<String>, Database.Stateful 
{
  public String[] headings;

  // pass your header string with instance. 
  public DI_batchProcessor(String header)
  {
    if (headings == null) 
    {
        headings = header.split(',');
    }
  }


  OR it can be done in start method instead of constructor
  public Iterable<String> start(Database.batchableContext batchableContext)
  {
    String csvHeader = csvFile.toString().split('line_separator')[0];
    if (headings == null) {
        headings = csvHeader.split(',');
    }

    // Now don't return header
    return new CSVIterator(csvFile, Parser.crlf);
  }

  // Execute is only for rows
  public void execute(Database.BatchableContext batchableContext, List<String> scope) 
  {
    if(headings != null)
    {
        // create the process of insertion here
    }
  }

  public void finish(Database.BatchableContext bc) {}

}
8
  • Is there any way not to put the headings in the constructor ? because I put my data inside Iterable<String> start(Database.batchableContext batchableContext).
    – Hope
    Sep 25, 2015 at 7:42
  • Id there not any way to get header first and then start your batch. And start*(...) iterator return only rows?
    – Ashwani
    Sep 25, 2015 at 7:46
  • I think the most efficient way is to process the data in batch iteration because when I try to process some data before iteration, I encounter lots of errors and limitation.
    – Hope
    Sep 25, 2015 at 8:01
  • @Hope you need to get header only before the batch.
    – Ashwani
    Sep 25, 2015 at 8:03
  • Do you mean that there is no way to make a variable being preserve in batch process ?
    – Hope
    Sep 25, 2015 at 8:30

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.