You can't always perform DML operations (insert, update, delete, etc...) on trigger context variables (trigger.new and the like).
+edit
It is possible to take records from Trigger.new
in an After Insert
trigger, and call DML update on them. I know, because I'm doing exactly that in some code for my org. The problem you're running into likely stems from attempting to DML update Trigger.new
in a block of code that can be reached when your trigger is already running before update
/edit
From that error that you're getting, it appears that Salesforce is also checking whether or not the collection of sObjects you're trying to run DML on exists in a trigger context variable (and complains if they do).
Salesforce is trying to protect you from yourself here. If Salesforce didn't do this, you'd be staring at a 'self reference from trigger' or 'maximum trigger depth exceeded' message instead.
If you are running a trigger before insert
or before update
, you don't need to run DML. If you modify a record in Trigger.new
or Trigger.newMap
in a before trigger (before insert
or before update
), those changes will automatically be saved.
This functionality won't help you out too much in this case though, because this trigger has deeper issues.
you would run into another issue when you try to build your email message. sObjects don't have an Id until after insert
.
To fix your trigger, you have two options:
Option 1
- Change
before insert
to after insert
, and before update
to after update
- Loop through trigger.new, perform your check for cases that should be closed
- DML update the list of cases that are being changed to 'closed'
- This should be done outside of your loop
- Build and send your emails in a block that only executes
after update
Option 2
- Instead of changing the Case status in a trigger, make this a workflow rule with a field update to close your case. You can choose to run this workflow rule on record creation only.
- Make this trigger fire
after update
only (since you wouldn't be updating the Case record in your trigger anymore, it's good practice to make it an 'after' trigger)
- Build and send your emails in a block that only executes
after update
You should also bulkify your email sending code. I'd need to do more research into an appropriate solution for this. My first instinct would be to loop through trigger.new, create new Messaging.SingleEmailMessage
instances, store them in a list, and then send all the emails once you're outside of the loop.
Best Answer
You can capture all the necessary DUNS_Number__c in a set and use the set to fetch your accounts