You need to sign in to do that
Don't have an account?
Pravin
too many dml rows 10001
Hi Team,
I am working on batch job which is operating on lots of records. I need to create opportunity sharing based on account sharing.I have written a batch job which is woking on account records 1000 as batch size. First i am taking all opportunity records linked to those accounts and passing the id of account and opportunity to a different normal apex class. In the for loop i am iterating on all the linked opportunity records (more than 10000 opp records linked to 1000 account records).When i am trying to create opp share records for those opp records and upserting them getting the below error
"too many dml rows 10001"
Please tell me the solution for this( instead of reducing the batch size).
My code snippet
Batch Job Execute method
global void execute(Database.BatchableContext BC, List<Sobject> scope){
List<Opportunity> opptyList = (List<Opportunity>)scope;
// Set<ID> oppIds = new Set<ID>():
Set<ID> accountIds = new Set<ID>();
Map<ID,Set<ID>> acctOppIDs = new Map<ID,Set<ID>>();
for(Opportunity oppty : opptyList) {
if(oppty.Sold_To_Account__c != null){
// oppIds.add(oppty.id);
accountIDs.add(oppty.Sold_To_Account__c);
if(acctOppIDs.get(oppty.Sold_To_Account__c) == null) {
acctOppIDs.put(oppty.Sold_To_Account__c, new Set<ID>());
}
acctOppIDs.get(oppty.Sold_To_Account__c).add(oppty.id);
}
//Update Opportunities Flag
oppty.SoldToChanged__c = false;
}
System.SavePoint pSavepoint = null;
if(accountIDs.size() >0) {
try {
pSavepoint = Database.setSavepoint();
ShareOpportunitiesUtil.shareOpptys(accountIDs, acctOppIDs);
//Update Opportunities Flag
upsert opptyList;
}catch(Exception ex) {
errorMsg +=ex.getMessage()+'\n';
Database.rollback(pSavepoint);
}
}
}
My normal Class
public without sharing class ShareOpportunitiesUtil {
public static void shareOpptys(Set<ID> accountIDs, Map<ID,Set<ID>> acctOppIDs) {
List<OpportunityShare> oppSharesList = new List<OpportunityShare> ();
for(AccountShare accShare :[Select a.UserOrGroupId, a.RowCause, a.OpportunityAccessLevel,
a.AccountAccessLevel, a.AccountID
From AccountShare a
where accountID in :accountIDs]) {
OpportunityShare oppShare = null;
for (String oppId :acctOppIDs.get(accShare.AccountID)) {
oppShare = new OpportunityShare();
oppShare.OpportunityId = oppId;
oppShare.UserOrGroupId = accShare.UserOrGroupId;
oppShare.OpportunityAccessLevel = 'Edit'; //HA changed to Edit accShare.AccountAccessLevel;
oppSharesList.add(oppShare);
}
}
try {
Database.upsert(oppSharesList,false);
}catch(Exception ex) {
System.debug('Exception occured');
throw ex;
}
}
}
Appreciate your help.
Thanks
Pravin
I am working on batch job which is operating on lots of records. I need to create opportunity sharing based on account sharing.I have written a batch job which is woking on account records 1000 as batch size. First i am taking all opportunity records linked to those accounts and passing the id of account and opportunity to a different normal apex class. In the for loop i am iterating on all the linked opportunity records (more than 10000 opp records linked to 1000 account records).When i am trying to create opp share records for those opp records and upserting them getting the below error
"too many dml rows 10001"
Please tell me the solution for this( instead of reducing the batch size).
My code snippet
Batch Job Execute method
global void execute(Database.BatchableContext BC, List<Sobject> scope){
List<Opportunity> opptyList = (List<Opportunity>)scope;
// Set<ID> oppIds = new Set<ID>():
Set<ID> accountIds = new Set<ID>();
Map<ID,Set<ID>> acctOppIDs = new Map<ID,Set<ID>>();
for(Opportunity oppty : opptyList) {
if(oppty.Sold_To_Account__c != null){
// oppIds.add(oppty.id);
accountIDs.add(oppty.Sold_To_Account__c);
if(acctOppIDs.get(oppty.Sold_To_Account__c) == null) {
acctOppIDs.put(oppty.Sold_To_Account__c, new Set<ID>());
}
acctOppIDs.get(oppty.Sold_To_Account__c).add(oppty.id);
}
//Update Opportunities Flag
oppty.SoldToChanged__c = false;
}
System.SavePoint pSavepoint = null;
if(accountIDs.size() >0) {
try {
pSavepoint = Database.setSavepoint();
ShareOpportunitiesUtil.shareOpptys(accountIDs, acctOppIDs);
//Update Opportunities Flag
upsert opptyList;
}catch(Exception ex) {
errorMsg +=ex.getMessage()+'\n';
Database.rollback(pSavepoint);
}
}
}
My normal Class
public without sharing class ShareOpportunitiesUtil {
public static void shareOpptys(Set<ID> accountIDs, Map<ID,Set<ID>> acctOppIDs) {
List<OpportunityShare> oppSharesList = new List<OpportunityShare> ();
for(AccountShare accShare :[Select a.UserOrGroupId, a.RowCause, a.OpportunityAccessLevel,
a.AccountAccessLevel, a.AccountID
From AccountShare a
where accountID in :accountIDs]) {
OpportunityShare oppShare = null;
for (String oppId :acctOppIDs.get(accShare.AccountID)) {
oppShare = new OpportunityShare();
oppShare.OpportunityId = oppId;
oppShare.UserOrGroupId = accShare.UserOrGroupId;
oppShare.OpportunityAccessLevel = 'Edit'; //HA changed to Edit accShare.AccountAccessLevel;
oppSharesList.add(oppShare);
}
}
try {
Database.upsert(oppSharesList,false);
}catch(Exception ex) {
System.debug('Exception occured');
throw ex;
}
}
}
Appreciate your help.
Thanks
Pravin
This error occurs usually when the total number of records processed by DML statements in greater than 10,000 ( Hitting on governor limit) and you can use for loop technique to reduce the number of records processed in single DML operation.
Kindly refer the below sample code to avoid this error:
Make a list here say:l1
Integer n=list.size();
Integer i=n/2;
For(integer j=0;j<10000;j++)
{
L1.add(list[i]);
}
Update l1;
Similarly you can iterate for next half set of records and can update your records in sets.
Note :This is a sample code and you need to modify this code as per your business requirements
Also you can try to populate the list and then do DML out from the loop. Please put the all DML statement outside from the for loop.
Further, I am providing you few links as below for your future reference:
1.https://help.salesforce.com/apex/HTViewSolution?urlname=Too-many-DML-rows-in-Apex-when-inserting-1327109077381&language=en_US
2.http://salesforce.stackexchange.com/questions/23253/how-does-salesforce-calculate-dml-rows-what-is-included-to-dml-rows-count
3.http://salesforce.stackexchange.com/questions/12514/system-limitexception-too-many-dml-rows-10001
4.http://salesforce.stackexchange.com/questions/15228/how-to-avoid-dml-insert-update-limit-of-10-000-rows-when-running-anonymous-apex
5.http://www.faqoverflow.com/salesforce/12514.html
" I hope this information has been helpful. If this has helped resolve your issue, please let us know by marking the post as "Best Answer" to help others in the community with similar questions. "
String query = 'SELECT id,name FROM Account WHERE id not in (select accountid from Contact )';
BatchClass_InsertContacts batchApex = new BatchClass_InsertContacts(query );
ID batchprocessid = Database.executeBatch(batchApex,10);
Thanks,
Krishna