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
Prathyu bPrathyu b 

How to get the failure record and failure reason when using databse.insert(). database.insert will throws null for getId() method when the insertion is failed. So, Can anyone help me to get the failure records list

Best Answer chosen by Prathyu b
Neha AggrawalNeha Aggrawal
Hi Prathyu,

That is possible too. As it clearly states in the link I have posted:
"Each element in the SaveResult array corresponds to the sObject array passed as the sObject[] parameter in the Database method, that is, the first element in the SaveResult array matches the first element passed in the sObject array, the second element corresponds with the second element, and so on."

You can simply match the index.
 
Account[] accts = new List<Account>{
    new Account(Name='Account1'),
    new Account(),
    new Account(Name='Account2'),
    new Account(Name='Account3'),
        new Account()};
        Integer i=0;
Database.SaveResult[] srList = Database.insert(accts, false);
for(Account a: accts)
{   
System.debug('Account'+i+'=(Name="'+accts[i].Name+'")'+'-'+srList[i].isSuccess()+'(Id: '+srList[i].getId()+')');
    i++;
}

This is the debug log:
USER_DEBUG|[12]|DEBUG|Account0=(Name="Account1")-true(Id: 0016F0000256BPkQAM)
USER_DEBUG|[12]|DEBUG|Account1=(Name="null")-false(Id: null)
USER_DEBUG|[12]|DEBUG|Account2=(Name="Account2")-true(Id: 0016F0000256BPlQAM)
USER_DEBUG|[12]|DEBUG|Account3=(Name="Account3")-true(Id: 0016F0000256BPmQAM)
USER_DEBUG|[12]|DEBUG|Account4=(Name="null")-false(Id: null)

Thanks.​

All Answers

Neha AggrawalNeha Aggrawal
Hi Prathyu,

I executed a simple code in my developer console:
 
Account[] acc= new List<Account>{
    new Account(Name='Account1'),
    new Account()};
Database.SaveResult[] srList = Database.insert(acc, false);
System.debug(srList);

Following is from the debug logs:
USER_DEBUG|[7]|DEBUG|(Database.SaveResult[getErrors=();getId=0016F000025610aQAA;isSuccess=true;], Database.SaveResult[getErrors=(Database.Error[getFields=(Name);getMessage=Required fields are missing: [Name];getStatusCode=REQUIRED_FIELD_MISSING;]);getId=null;isSuccess=false;])

You can get the failure reason from getErrors and getMessage methods above. Please see the below link for more information:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_database_saveresult.htm#apex_methods_system_database_saveresult

Thanks.


 
Prathyu bPrathyu b
Thanks Neha, For the response.
Here is my questions:

Ex: I am trying to insert 10 accounts using database.insert like below :

account 1 = (Name = 'accoun1');
account 2 = (Name = );
account 3 = (Name = 'accoun2');
account 4 = (Name = 'accoun3');
account 5 = (Name = );
account 6 = (Name = );
account 7 = (Name = 'accoun4');
account 8 = (Name = 'accoun5');
account 9 = (Name = );
account 10 = (Name = 'accoun6');

In the above case Account 2,5,6,9 will get failed as the required field is missing. So I need output as below on the page/ excel :

account 1 = (Name = 'accoun1') - Success(Id: 001XXXXX--)
account 2 = (Name = );  - Failed
account 3 = (Name = 'accoun2'); - Success(Id: 001XXXXX--)
account 4 = (Name = 'accoun3'); - Success(Id: 001XXXXX--)
account 5 = (Name = ); - Failed
account 6 = (Name = ); - Failed
account 7 = (Name = 'accoun4'); - Success(Id: 001XXXXX--)
account 8 = (Name = 'accoun5'); - Success(Id: 001XXXXX--)
account 9 = (Name = ); - Failed
account 10 = (Name = 'accoun6'); - Success(Id: 001XXXXX--)

Is tehre anyway to display the output as above.
Neha AggrawalNeha Aggrawal
Hi Prathyu,

That is possible too. As it clearly states in the link I have posted:
"Each element in the SaveResult array corresponds to the sObject array passed as the sObject[] parameter in the Database method, that is, the first element in the SaveResult array matches the first element passed in the sObject array, the second element corresponds with the second element, and so on."

You can simply match the index.
 
Account[] accts = new List<Account>{
    new Account(Name='Account1'),
    new Account(),
    new Account(Name='Account2'),
    new Account(Name='Account3'),
        new Account()};
        Integer i=0;
Database.SaveResult[] srList = Database.insert(accts, false);
for(Account a: accts)
{   
System.debug('Account'+i+'=(Name="'+accts[i].Name+'")'+'-'+srList[i].isSuccess()+'(Id: '+srList[i].getId()+')');
    i++;
}

This is the debug log:
USER_DEBUG|[12]|DEBUG|Account0=(Name="Account1")-true(Id: 0016F0000256BPkQAM)
USER_DEBUG|[12]|DEBUG|Account1=(Name="null")-false(Id: null)
USER_DEBUG|[12]|DEBUG|Account2=(Name="Account2")-true(Id: 0016F0000256BPlQAM)
USER_DEBUG|[12]|DEBUG|Account3=(Name="Account3")-true(Id: 0016F0000256BPmQAM)
USER_DEBUG|[12]|DEBUG|Account4=(Name="null")-false(Id: null)

Thanks.​
This was selected as the best answer
Prathyu bPrathyu b
Thanks Neha, I worked .

I have tested the functionality with 10 records and only 1 standard validation. 
But if i have a case to test both standard and custom validations around 10(validations) will it works as expected?
And If i have to insert 2000 records will it work without any failures?
I mean will it follw - first IN first PROCESS?
Did you try uploading more than 1000 records with this scenario.