You need to sign in to do that
Don't have an account?
Vinnie B
Getting "Too many DML rows: 10001" but I only have 5,000 rows to insert
I understand that you can't insert more than 10,000 rows at once in a DML statement. So, I wrote a little routine to do these 5,000 at a time (below). Note that this is called in the 'finish' function of the batch process so it's gathered all of the relevant records, some 50,000 or so.
This code seems to be working well, but I'm still getting the error message. Note that in my logs below it says it's only going to insert 5,000 records but then the next line says that's over 10,000. Am I missing something as to what constitutes a "DML row". I'll try again using a batch size of 1,000 and see how that goes.
11:27:54.704 (31704666000)|DML_BEGIN|[94]|Op:Insert|Type:STB_Constituent__c|Rows:5000
11:27:54.704 (31704687000)|EXCEPTION_THROWN|[94]|System.LimitException: Too many DML rows: 10001
11:27:54.704 (31704768000)|HEAP_ALLOCATE|[94]|Bytes:28
11:27:54.706 (31706178000)|FATAL_ERROR|System.LimitException: Too many DML rows: 10001
for (ID cID : contactIDs) {
counter ++;
STB_Constituent__c stbc = new STB_Constituent__c();
stbc.Contact_ID__c = (String) cID;
constituents.add(stbc);
if (counter == 5000) {
try {
insert constituents;
counter = 0;
constituents.clear();
} catch (System.DmlException dmlEx) {
throw dmlEx;
}
counter ++;
STB_Constituent__c stbc = new STB_Constituent__c();
stbc.Contact_ID__c = (String) cID;
constituents.add(stbc);
if (counter == 5000) {
try {
insert constituents;
counter = 0;
constituents.clear();
} catch (System.DmlException dmlEx) {
throw dmlEx;
}
This code seems to be working well, but I'm still getting the error message. Note that in my logs below it says it's only going to insert 5,000 records but then the next line says that's over 10,000. Am I missing something as to what constitutes a "DML row". I'll try again using a batch size of 1,000 and see how that goes.
11:27:54.704 (31704666000)|DML_BEGIN|[94]|Op:Insert|Type:STB_Constituent__c|Rows:5000
11:27:54.704 (31704687000)|EXCEPTION_THROWN|[94]|System.LimitException: Too many DML rows: 10001
11:27:54.704 (31704768000)|HEAP_ALLOCATE|[94]|Bytes:28
11:27:54.706 (31706178000)|FATAL_ERROR|System.LimitException: Too many DML rows: 10001
All Answers
BTW, I brought the number down from 5000 to 100 based on another thread I saw. That doesn't seem to be working either. :( I'll keep at it.
<pre>
System.debug('contactIDs size = ' + contactIDs.size());
</pre>
I understand the batching process. In my code I have a list that is added to on every execute function. Once I get to the finish function, this list has tens of thousands of records. I was doing my inserts at this point in the code (iterating through this list in the finish function). I will try and do the inserts as part of the execute function instead. That should work as each batch is a separate execution.
However, I also have code that deletes all prior records prior to starting out. I can't do this as part of the batch process. I'm wondering if a separate function in another class would work. As I get to the limit instead of trying to do the update there, I simply pass the batched portion of the list to another function that will do the deletion or insertion for me. Would that work or would this count as DML rows in my current batch class?
You can either do the deletes in a clever way that allows you to do the deleting of associated old records right before adding the new ones, or you can schedule a batch to fire some time before the current batch and have it do the deletions.
<pre>
global class BatchContacts
{
public Database.queryLocator start()
{
return new Database.queryLocator('SELECT Id FROM Contact');//Let's pretend this returns 100,000 records
}
public void execute(List<Contact> scope)
{
System.debug('scope size = ' + scope.size());//This will come as 200
delete [SELECT Contact__c FROM STB_Constituent__c WHERE Contact_Id__c IN :scope];
List<STB_Constituent__c> constits = new List<STB_Constituent__c>();
for (Contact cont: scope)
{
constits.add(new STB_Constituent__c(Contact_Id__c = cont.Id);
}
insert constits;
}
public void finish()
{
//Do your finish stuff in here
}
}
</pre>
- all constituent records (I need to remove them all)
- a specific set of contacts that will be considered constituents
THANKS again for all of your help!! I think I can run with this for a little while anyway.