I want to create a script that will insert 1 million records of OpportunityContactRole.

I have 1 million Opportunities as well as 1 million Contacts and i want to create record of 1 OpportunityContactRole over 1 opportunity and 1 contact.I mean all OpportunityContactRoles records should be on distinct opportunity and contact.

How can i achieve this?

  • (1) How do you know which Contact on the Oppo's Account becomes the OCCR? and (2) Did you read about Apex batch jobs?
    – cropredy
    Commented Nov 3, 2015 at 1:16
  • Actually this script is just for testing purpose.So i don't have any concern about the Oppo's Account.I just want to relate one oppo with one contact.Without repeating any oppo or contact i want to create 1 million OCR. And yes i'm aware of batches.Actually i'm hitting lots of limits during creation of such script.I'm still trying.
    – Mr.Frodo
    Commented Nov 3, 2015 at 6:21
  • Did you also create the 1,000,000 Opportunities and the 1,000,000 Contacts? If so then you would have a much easier time creating Opp / Contact / OppContactRole at the same time in a batch operation as you will know the Opp and the Contact IDs that you want to join
    – Doug B
    Commented Nov 6, 2015 at 12:14

2 Answers 2


You can create two custom fields on both the object isProcessed(boolean). Now in the batch you should query the Opportunities and Contacts in which isProcessed is false and then create record of OpportunityContactRoles and assign one Opportunity to one Contact as well as update the isProcessed field to true for both the objects(Opportunities and Contacts). Schedule the batch again in finish method.

  • Thanks @Hitesh for your suggestion.I was flexible with this approach and i have followed the same here.I have shared my script.+1 for your answer.
    – Mr.Frodo
    Commented Nov 7, 2015 at 6:45

Thanks guys for your suggestions.I had created a script and was able to insert those records.I'm sharing the script here.Maybe it's is not that optimized as i just want to create it for testing purpose.

global Iterable<sObject> start(Database.BatchableContext BC){
    sList=new List<sObject>();
    oppList=[Select id, IsQueried__c from Opportunity where IsQueried__c=false Limit 20000];
    conList=[Select id, IsQueried__c from Contact where IsQueried__c=false Limit 20000];

     for(Integer i=0;i<oppList.size() && i<conList.size();i++){
        OpportunityContactRole ocr=new OpportunityContactRole(OpportunityId=oppList[i].Id, Role  = 'Decision Maker',ContactId=conList[i].Id);
    return sList;     
 * Name : execute
 * Description : process batches
global void execute(Database.BatchableContext BC, List<sObject> scope){
    List<Opportunity> tempOppList=new List<Opportunity>();
    List<Contact> tempConList=new List<Contact>();
    List<OpportunityContactRole> ocrList= new List<OpportunityContactRole>();

    for(sObject s:scope){
            Contact c=(Contact)s;
        else if(s.getSObjectType().getDescribe().getName()=='Opportunity'){
            Opportunity o=(Opportunity)s;
            OpportunityContactRole o=(OpportunityContactRole)s;
    //if list is not blank then delete all records
    update tempOppList;
    update tempConList;
       insert ocrList;

 * Name : finish
 * Description :finish method for post processing. 
global void finish(Database.BatchableContext BC){
        List<sObject> sL=[Select Id from Opportunity where IsQueried__c=false limit 1];

        if(sL!= null){
    //execute batch again
        CleanOrgBatch batch = new CleanOrgBatch();


Not the answer you're looking for? Browse other questions tagged .