1

I have a specific use case where I would like to insert records with:

List<Database.SaveResult> srList = Database.insert(contacts, true);

But also to get that SaveResult returned and to be able to iterate through that object to log failures for each record separately.

When allOrNone parameter is set to true and if any of the records fail then Database.insert() will throw an exception and roll back the transaction. I want to keep the default functionality of rolling back the records, but also want the ability to iterate through results and pinpoint the exact records that failed.

Is such a thing possible?

1 Answer 1

3

DmlException has the information you're looking for, just in a different format. In other words, allOrNone being true doesn't give you the Database.SaveResult[] values, but this information is still available in the exception itself:

try {
  insert contacts;
} catch(DmlException e) {
  for(Integer index = 0; index < e.getNumDml(); index++) {
    System.debug('Contact at '+ e.getDmlIndex(index) + ' failed to save.');
    System.debug('The error was '+e.getDmlMessage(index));
    System.debug('The error type was '+ e.getDmlType(index));
  }
}

And so on.

The exception is slightly more efficient, though, as it only returns the exception rows, so you don't need to check isSuccess for every row, as you'd have to do with a SaveResult[].

You can, however, use allOrNone set to false, and then use a SavePoint to manually roll back any changes to the database up to that point:

Savepoint sp = Database.setSavePoint();
Database.SaveResult[] results = Database.insert(contacts, false);
if(anyErrorsIn(results)) {
  Database.rollback(sp);
}
1
  • sfdcfox, you never dissapoint, thank you! Sep 7, 2023 at 12:25

You must log in to answer this question.

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