2

Scenario:

I've written an apex class and trigger that pulls data from a child record and displays the information in a text field in a certain manner.

From hence on forth, anytime the code is triggered, it will update the parent record correctly.

Question:

What are the different ways in which to ensure the old records are also displaying this new information correctly?

Here are some options that I have come across when doing this research:

  1. Data Loader - Manually uploading the corrected format
  2. Batch Apex Class - pushing this to production and calling it in anonymous apex. Q: Do you keep this class in production or subsequently delete it since you're only ever using it once?
  3. Running the code in Anonymous Apex. I'm assuming this is the least popular option.

Final question: Are options number 2 and 3 what people mean when they say they'll run a script in Salesforce or is there another option(s) that I've not mentioned above?

Thank you!

2

What are the different ways in which to ensure the old records are also displaying this new information correctly?

Data Loader, Import Wizard, Batch Class, Queueable Class, Execute Anonymous, etc. Anything that can modify every record in the database in a single pass. It'll be different depending on if you have 5k records or 50m records as to which approach would be best.

Data Loader - Manually uploading the corrected format

Addressing this and any other ETL (Extract Transform Load) tool. You only need to export the ID values and then perform an update. You don't need to correct anything (that's why you built the trigger/flow/etc, right?).

Batch Apex Class - pushing this to production and calling it in anonymous apex. Q: Do you keep this class in production or subsequently delete it since you're only ever using it once?

You could do that, or you could build a Swiss Army Knife Batch Apex class. That's what we use in production, and it's pretty much only used for one-off purposes. Having a plug-and-play Batchable boilerplate lets us do one-off commands, and in a more modern iteration, also lets us disable most triggers (our trigger code is designed to skip triggers when a static variable is set) if we want to (obviously, not in your case, though, you want the records to be updated via trigger).

Final question: Are options number 2 and 3 what people mean when they say they'll run a script in Salesforce or is there another option(s) that I've not mentioned above?

That's usually what's meant, more 2 than 3, though other platforms, such as Informatica, also allow you to devise scripts of sort for doing specific updates in bulk. Salesforce has been around long enough now that all kinds of people have built all kinds of solutions.

1
  • Thank you for the really detailed answer. It was extremely helpful. Thank you for also sharing your Swiss Army Knife Batch Apex class! – Tom G Apr 21 at 15:09
1

This is a question that's haunted me throughout my time in Salesforce. What's the best practice for "running scripts", whatever that means.

Here are methodologies that our team has found to be effective:

  1. Build the script into an apex trigger that runs when a checkbox is checked. In the before trigger, the checkbox is automatically unchecked. Next (depending on the script), either in the before or after trigger, the actual logic is performed. Then, create a workflow rule, record-triggered flow, or process builder diamond that checks the box when criteria on the record is met (to handle the moving-forward scenario). Putting the conditions in a declarative tool allows us to agily change them whenever the business need changes. Finally, run a dataload to check the box on all historical records that we care about (typically "open" records)
  2. Build the script into a change event trigger (a special kind of platform event that listens for changes to a record). The moving forward scenario is handled by listening for specific field updates. Then to accommodate backfilling etc., we have a multi-select picklist with values for each type of functionality, and can select the functionality that we want to run in a dataload, similar to the checkbox solution above. Once the functionality has run, the change handler then clears the multi-select box. This model is good for functionality that can run in the background, rather than directly on record updates.
  3. By far our favorite solution has been a recent addition to our arsenal. We created a separate object ("Fulfillment Action") dedicated specifically to running various kinds of scripts related to the fulfillment of opportunities. Each fulfillment action has a lookup to an opportunity, a "Type" field that determines which script to run, a "Status" field that contains the results of the run, a "Messages" field containing any error messages, and various other data points specific to individual scripts. We then created an app for users to run actions related to an opp, as well as an overnight scheduled job that runs actions in bulk. When the opp becomes ready for fulfillment, relevant actions are generated for it, and users can see ahead of time what the system is planning to do, as well as any errors encountered from executed actions (because errors are stored on the action record, rather than obscured by the overnight job). You can report on script results, dataload to run them, and do all kinds of things by tying each script to a standardized object that runs and manages it.

enter image description here

So we've basically moved to #1 in your list -- using dataloader, because it gives us the greatest flexibility in determining the criteria of which records are included. But instead of manually creating the dataloaded information, we rather dataload a flag that causes the system to calculate it.

Batch apex on the other hand requires you to specify your criteria in Apex (without some clever custom metadata options etc.), so while our org began there, we moved away from it. Our scheduled job for #3 runs a query against open fulfillment actions, and publishes platform events to run each one. This gives us the ability to replay actions with a hard failure due to transient errors, and if there is a hard failure (like a CPU timeout), it only stops a small subset of actions from running. When batch apex and queueables experience a hard failure, they kill the entire process, including any good records that follow the bad.

Hope that helps, ~Nate

2
  • 1
    Thank you for the very in-depth answer and it's extremely helpful! All three methodologies listed have kind of opened my eyes a bit more, if you will. #3 in particular is pretty phenomenal. – Tom G Apr 21 at 15:58
  • Thanks! Took us years of trial and error and pain to determine how we really wanted to approach this issue, and finally putting the working into fulfillment actions has definitely paid off. – Nathanael Schmolze Apr 21 at 23:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.