Finding deleted records in Salesforce using SOQL and Apex
By Jeff Ballard
We were recently engaged to assist a new client with their Salesforce implementation and asked to determine why a process builder process had been intermittently failing. The process builder was attempting to set the OwnerId on an opportunity by finding the value on a record related to the opportunity.
I had the ID for the opportunity the process builder was executing against and wanted to look at the values on the related record to see if I could figure out why it failed. So, I copied the Opportunity ID from my process builder error, opened a different opportunity and replaced the ID in the URL — and I got a notice that the record didn’t exist.
Was it deleted? Well, I only had the Id, and when I looked in the recycle bins (both user and system), there were lots of records, and I couldn’t see the Id in the recycle bin. How could I find out if the record I was looking for was in the recycle bin? You’d think it would be as easy as firing up the developer console and executing this SOQL:
Select Id, name from Opportunity where ID = ‘<your ID here>’ and IsDeleted = true
Since I’m writing this, it’s obviously not that easy. There are two more pieces to the puzzle. The first piece in the puzzle is you need to include the ALL ROWS keywords in your SOQL statement:
Select Id, name from Opportunity where ID = ‘<your ID here>’ and IsDeleted = true ALL ROWS
If you try that in the developer console, though, you’ll get an “Unknown error parsing query” message.
That’s where the second piece of the puzzle comes in: You can only include ALL ROWS in Apex code. So, to execute the query, you need to open the anonymous code window from the developer console by pressing Ctrl-E. When you do that, you can enter code similar to the blow:
List<opportunity> deletedOpps = [select id, name from opportunity where isDeleted = true and Id = '<RecordIdGoesHere>' ALL ROWS];
system.debug(deletedOpps);
When you execute that, it will output the results to the Logs tab in the developer console, and you can check the “Debug only” checkbox. It will filter the log to your debug output, which will show the records it found.
Note that in this case, the isDeleted = true in the where clause works with the ALL ROWS keywords. If you don’t include any where clause, but do include ALL ROWS, then you will get all records, deleted and active. But, by adding the where isDeleted = true, you get only those records in the recycle bin.
If you have any questions about finding deleted records in Salesforce, contact Wipfli. You can also read more technology-focused articles here.