html code

Retrieving Failed Records from Database.Insert/Upsert | Salesforce Developer Guide

Salesforce offers diverse options for DML operations. Imagine a scenario where the requirement involves saving file data into the database, with Salesforce supporting only CSV file formats, necessitating adherence to the CSV format as the initial step.

Subsequently, after file retrieval, distinct methods apply for Visualforce and Aura Lightning Components. In Visualforce, you employ <apex:input> to read the file, while in Lightning Components, FileReader() is utilized. Once the file data is obtained, it exists either as a blob (Visualforce Page) or an encoded base64 String (in Aura), necessitating its transfer to an Apex class.

Header1 Header 2 Header 3 Header 4 Header 5
Data 1 for header 1    Data 1  for header 2   Data 1  for header 3Data 1  for header 4 Data 1  for header 5 
Data 2 for header 1Data 2 for header 2Data 2 for header 3Data 2 for header 4Data 2 for header 5

Component:

<div class="select-upload slds-m-left_x-small">
    <lightning:input label="Select File" class="upload-btn select-btn" aura:id="fileId"  onchange="{!c.uploadClaimForm}" type="file" name="filetype"  multiple="false"/>
</div>

Controller:

var files = component.find("fileId").get("v.files");
if (files && files.length > 0) {
    var file = files[0];
    var reader = new FileReader();
    reader.onloadend = function() {
        var dataURL = reader.result;
        var content = dataURL.match(/,(.*)$/)[1];
        var fileName = file.name;
        var contentType = file.type;
        var base64Data = content;
        // set your data in an attribute
        component.set("v.encodedUploadedFileData",base64Data);
        //set the file name in a n attribute
        component.set("v.encodedUploadedFileName",fileName);
        //set content type in an attribute
        component.set("v.encodedUploadedFileContenttype",contentType);
    }
    reader.readAsDataURL(file);
}

Once the data is retrieved, transmit it to the server-side.

Helper:

var action = component.get("c.uploadFile");
action.setParams({
    "parentId": component.get("v.recordId"),
    "fileName": component.get("v.encodedUploadedFileName"),
    "base64Data": component.get("v.encodedUploadedFileData"),
    "contentType":component.get("v.encodedUploadedFileContenttype")
});

Apex Class:

public static void main uploadDataintoDatabase(String parentId, String fileName, String base64Data, String contentType){
    //read you data from the base64Data and create a list for the records from base64Data
    // after you have saved the records in a list named recordsToUpload, you have to save them
    Database.UpsertResult [] listUpsertResult = Database.upsert(recordsToUpload , false);
}

After inserting or upserting the records in the database, determining the successful entries is straightforward—they have assigned IDs. However, identifying the failed records, which lack IDs due to errors, poses a challenge. How can you discern which records encountered issues and failed to be processed?

Begin by iterating through your records list using a loop, where the second loop iterates through the header values of your file.

for (Integer i = 0; i < recordsToUpload.size(); i++) {
    Database.UpsertResult upsertResultValue = listUpsertResult[i];
    if (!upsertResultValue.isSuccess()) {
        //create csv file data for error records
        for(Database.Error err : upsertResultValue.getErrors()){
            //in case of error, get all the records on that index
            String getEachRecord = '';   
            // header values contains header1, header 2, header 3, heder 4, header 5                    
            for(String headerValue:headerValues){
                if(getEachRecord != null || getEachRecord!=''){                                  
                    getEachRecord =  getEachRecord+ recordsToUpload[i].get(headerValue);
                    getEachRecord = getEachRecord.removeEnd('\n')+',';
                }else{
                    getEachRecord = recordsToUpload[i].get(headerValue)+',';
                }
            }
            //add the reason of error in the string
            String replaceErrorMessage = err.getMessage();
            List<String> errorFields = err.getFields();
            String strErrorFields = String.valueOf(errorFields);
            System.debug('@@err.getFields()'+err.getFields());
            System.debug('@@StrErrorFields'+strErrorFields);
            getEachRecord =  getEachRecord+err.getFields()
            +err.getMessage()
            +'\n';
            getEachRecord = getEachRecord.remove('\r');
            //add the final string in the list
            listRecordsToUploadError.add(getEachRecord);
        }
    }else{
        //create csv file data for success records
        String getEachRecord = '';
        for(String headerValue:headerValues){
            if(getEachRecord != null || getEachRecord!=''){
                getEachRecord =  getEachRecord+ recordsToUpload[i].get(headerValue)+',';
            }else{
                getEachRecord = recordsToUpload[i].get(headerValue)+',';
            }
        }
        getEachRecord = getEachRecord.removeEnd(',');
        getEachRecord =  getEachRecord +'\n';
        getEachRecord = getEachRecord.remove(',,');                                                                                 listRecordstoUploadSuccess.add(getEachRecord);
    }
}

Now, you’ll have data that includes both the error fields and the successful records.