Kick Anonymous Apex into high gear — without inadvertently destroying your database

Anonymous Apex can be extremely useful when trying to perform complex, cross-object, bulk data manipulation tasks that might only need to be done once, and never used again. For such situations, writing a piece of code to achieve your functionality, writing test code, and deploying it to production — when you might never use the code again — doesn’t make much sense. Enter Anonymous Apex!

However, using Anonymous Apex can potentially be VERY dangerous. You could royally mess up a lot of data, and never even know until it was too late. Unless…

You take some precautions.

What if you could verify that your long, convoluted Anonymous Apex routine was actually doing what it was supposed to do as it proceeded, similar to the way Apex Unit Tests work with System.asserts?

Well, you can! Anonymous Apex supports all of the System.assert statements, AND it supports Database.rollbacks. When the two are used in tandem, you get a powerful disaster prevention mechanism that makes Anonymous Apex a lot less risky and hackish.

Example 1: Find all unresolved, non-high Priority Cases over a year old related to major Accounts (i.e. those with really big Closed Opportunities, and make them High or Critical priority, and Escalate them to the top Service representative

List bigDeals = 
	[select AccountId 
	from Opportunity
	where Amount > 400000 
	and StageName = 'Closed Won']; 
// Sanity check --- make sure we found some deals
System.assert(bigDeals.size() > 0,
	'We did not find any Big Deals'); 

Set accountIds = new Set(); 
for (Opportunity opp : bigDeals) {
	if (!accountIds.contains(opp.AccountId)) {
// Sanity check
System.assert(accountIds.size() > 0, 
	'We did not find any Account Ids'); 

List unresolvedCases = 
	[SELECT Id, Priority, Status, Reason 
	FROM Case 
	WHERE Status != 'Closed' 
	AND AccountId in :accountIds 
	AND Priority not in ('High','Critical')
	AND CreatedDate = TODAY]; 

// Sanity check 
System.assert(unresolvedCases.size() > 0,
	'We did not find any unresolved Cases tied to our Big Deals'); 

// Find our best Support Rep,
// to whom we will reassign our highest priority cases
User awesomeRep = 
	[select id,LastName 
	from User 
	where Email = '' 
	limit 1];
// Make sure we found the User we think we did
System.assertNotEquals(null, awesomeRep, 'awesomeRep'); 
	'Rep Last Name',

Integer numDefects = 0;
Integer numOtherCases = 0; 

for (Case c : unresolvedCases) { // Escalate the case
	c.Status = 'Escalated'; 
	// If the Case Reason is 'Defect', 
	// the Priority should be 'Critical' 
	if (c.Reason == 'Defect') { 
		c.Priority = 'Critical';
	// Otherwise, Priority should be 'High' 
	else { 
		c.Priority = 'High'; 
	// Set the Owner to 
	if (c.OwnerId != awesomeRep.Id) c.OwnerId = awesomeRep.Id; 
// Sanity check
System.assert(numDefects > 0 || numOtherCases > 0, 
	'we only want to proceed '
	+ 'if we updated at least some of our cases'); 

// Sanity check --- force code to stop here
// to let us examine how things went 
// before we actually do the update
System.assert(false,'Sanity Check!'); 

Savepoint sp = Database.setSavepoint();
try { 
	update unresolvedCases; 
} catch (Exception ex) { 
	// If we catch any errors, 
	// rollback the database to how it was 
	// prior to the DML call
	// Then display the exception

I often find that code that starts out as Anonymous Apex routines eventually makes its way into actual classes / controllers / triggers —- and Unit Tests.

If you haven’t used Anonymous Apex before, you can use it from all sorts of locations — from the System Log (old or new — the new version has excellent code/syntax highlighting), from the IDE, or from SoqlXplorer (on the Mac)).

2 thoughts on “Kick Anonymous Apex into high gear — without inadvertently destroying your database

  1. Hello! I just want to give you a big thumbs up for your excellent info you’ve got right here on this post. I will be coming back to your blog for more soon.

  2. Hiya very cool website!! Man .. Excellent .. Amazing .. I’ll bookmark your web site and take the feeds also? I’m satisfied to seek
    out a lot of useful information right here in the post, we’d like develop extra techniques in this regard, thank you for sharing. . . . . .

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s