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
SYM12SYM12 

System.Exception: Too many DML rows:

Hi All,

 

I am updating opportunities while updating the Account Owner.

 

Opportunities are more than 100 , so i divided into batches of 50 

 

but i am still getting the DML execption while updating 300 records ( max DML satatements should be 6)

 

\Error: Apex trigger PAMUpdate caused an unexpected exception, contact your administrator: PAMUpdate: execution of BeforeUpdate caused by: System.Exception: Too many DML rows: 147: Trigger.PAMUpdate: line 63, column 5

 

 Here is my complete snipped of code

 

trigger PAMUpdate on Account (before update) {

    Map <Id, String> acc = new Map <Id, String>();

    List<String> accountList = new List<String>();

    for (Account a : Trigger.new)

    {

        String oppOwner = Trigger.oldMap.get(a.Id).OwnerId;

        if (a.IsPartner == true && a.OwnerId != oppOwner)

        {           

            accountList.add(a.Id);

        }

    }
  //  System.debug(' Accounts are ' + accountList );
   // System.debug(' Account Size is =  ' + accountList.size() );
 
   
 List<Opportunity> oppList = new List<Opportunity>();

    if(accountList.size()>0)

    {  

        oppList  = [select PAM__c,PartnerAccountId from Opportunity

                                     where PartnerAccountId In : accountList limit 300];

        }
        for(Opportunity oppRec:smileysurprised:ppList)

        {

            oppRec.PAM__c = Trigger.newMap.get(oppRec.PartnerAccountId).OwnerId;

        }

       
 if(oppList.size() > 50){
       List<Opportunity> subList = new List<Opportunity>();

for(Opportunity record : oppList){

subList.add(record);

if(subList.size()==49){

try{
    update subList;  }
    catch(Exception ex){
            System.debug(' Exception Occured' + ex);}
subList.clear();
}
}
if(subList.size() > 0){

try{
    update subList;  }
    catch(Exception ex){
            System.debug(' Exception Occured' + ex);}
}

}else{

try{
    update oppList;  }
    catch(Exception ex){
            System.debug(' Exception Occured' + ex);}

} }

 

Please suggest if i am doing any thing wrong while updating .

 

Thanks in advance

XactiumBenXactiumBen
Your problem is not the number of DML statements but the number of records you are retrieving from your SOQL statement.  I believe the issue is that you're trying to get 147 opportunities out of one account when the limit only allows for 100 opportunities per account.  Don't think there is anything you can do about this in a trigger unless you want to go down the route of using batch apex.
SteveBowerSteveBower

Aside from suggestions on cleaning up the code a bit, I think the previous poster is correct.  If you only have one row in your trigger, you're limited to 100 DML records to process.  So, I wonder if you can cheat.    I'm not sure, but it seems logical... :-)  Best, Steve.

 

 

trigger PAMUpdate on Account (before update) { // I'm wondering if you can cheat... I don't know if this would realy work or not... // Check the size of the trigger array, and if it's only one, do a fake update of the same // Account twice. When it comes through the next time, there will be two records in Trigger.new // thus raising your DML records limit to 200. But, since you're really only processing // the Opportunities, and not touching the Accounts anyway, it doesn't matter. // Note, instead of just doing this all the time, you could do a // Select count from Opportunity... first and only do this if there // are more than 100... if (Trigger.new.size() == 1) { update(new Account[]{Trigger.new[0],Trigger.new[0]}); return; } // and the code below is a little cleaner... // Note: I'm just typing this all in by hand... it's probably got some issues.... Set<String> accountSet = new Set<String>(); for (Account a : Trigger.new) { String oppOwner = Trigger.oldMap.get(a.Id).OwnerId; if (a.IsPartner == true && a.OwnerId != oppOwner) { accountSet.add(a.Id); } } // System.debug(' Accounts are ' + accountList ); // System.debug(' Account Size is = ' + accountList.size() ); List<Opportunity> oppsToUpdate = new List<Opportunity>(); for(Opportunity oppRec: [select PAM__c,PartnerAccountId from Opportunity where PartnerAccountId In : accountSet limit 300]) { oppRec.PAM__c = Trigger.newMap.get(oppRec.PartnerAccountId).OwnerId; oppsToUpdate.add(oppRec); if (oppsToUpdate.size() == 200) { try { update oppsToUpdate; oppsToUpdate.clear(); } catch(Exception ex) { System.debug(' Exception Occured' + ex); } } } if (! oppsToUpdate.isEmpty()) { try { update oppsToUpdate; oppsToUpdate.clear(); } catch(Exception ex) { System.debug(' Exception Occured' + ex); } } }

 

 

 

SYM12SYM12

while use the code above i am getting an error

 

Error: Apex trigger PAMUpdate caused an unexpected exception, contact your administrator: PAMUpdate: execution of BeforeUpdate caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old: Trigger.PAMUpdate: line 13, column 6

 

Also i am use the batches of 50 so can't i upadte the record upto 300 with 6 batches of 50 ( as it will include on 6 DML statements) . As per my understanding i can update 100 records in 1 batch

SteveBowerSteveBower

Well, perhaps you can't cheat this way, or perhaps you just need to use this instead of the one update line.

 

List<Account> tryThis = new List<Account>();

tryThis.add(new Account(id=trigger.new[0].id,isPartner=trigger.new[0].isPartner,ownerId=trigger.new[0].ownerid);

tryThis.add(new Account(id=trigger.new[0].id,isPartner=trigger.new[0].isPartner,ownerId=trigger.new[0].ownerid);

tryThis.add(new Account(id=trigger.new[0].id,isPartner=trigger.new[0].isPartner,ownerId=trigger.new[0].ownerid);

update tryThis;

 

 

It was just a thought.   I know it's goofy to update the same record several times in one update statement, but they allow up to five (I think) duplicate ID's in a statement before they flag it as errors.  So, if you know the max is 300 you could insert it 3 times to get up to 300 DML records.

 

You can update 200 records in one statement.   So to do 300 do one of 200 and one of 100 instead of  six of 50.

 

 

So, this is all just cheating which I don't normally advocate, but it seems like it might work for you in some limited curcumstances.  (Or perhaps the system will catch it... I don't know.)

 

Good luck, Steve.

SYM12SYM12

Steve ,Actually problem is that i have more than 1000 opportunities to update. I was just giving a trial with 300. If trigger has limit to update 100 DML at a time , so can't we create batches of 100 ( Beacuse the DML Statement limit is 20) . so with that we can update 100 *20 = 20,000 records.

 

Please suggest

SteveBowerSteveBower
Force.com Discussion Boards Subscription: 1 New Post: Re: System.Exception: Too many DML rows:BODY { FONT: 10pt Arial, Helvetica } TD { FONT: 10pt Arial, Helvetica }
Oh, forget triggers then... It's not a limit of 100 records in a single invocation of a trigger... it's a limit of 100 records for each record in the trigger.   So, if one Account change is going to require the updating of 1000+ Opportunities, then I think you have to look at doing it another way.  Use an external tool to pull the data, modify it and reinsert it, or perhaps use Batch Apex on all your Opportunities to just run through them all and make sure the fields are set the way you want.
 
Best, Steve.
 
p.s. If I were to step into the business analyst role for the moment I might ask why a single account has 1000+ open opportunities, but that's a different issue.
SYM12SYM12
Steve thnaks for the suggestion, Actully i am using now @ future call , But facing difficulties to test my code. As  this call dont log all the debug stestments............ :(