0

When querying ContentDocumentLink in SOQL using the following query, an error is thrown.

Goal: We are attempting to get a spreadsheet of the data so we can update IsDeleted flag with TRUE on entries that we need to remove. Given that we can't even query at the moment, is this even possible to do through Data Loader upsert?

Select Id, LinkedEntityId, ContentDocumentId, IsDeleted, SystemModstamp, ShareType, Visibility FROM ContentDocumentLink WHERE ContentDocumentId IN (SELECT Id FROM ContentDocument)

Error:

Implementation restriction: ContentDocumentLink requires a filter by a single Id on ContentDocumentId or LinkedEntityId using the equals operator or multiple Id's using the IN operator.
2

This is a system restriction on ContentDocumentLink. The object reference has specifics of what you're required to do:

You can't run a query without filters against ContentDocumentLink.

You can't filter on ContentDocument fields if you're filtering by ContentDocumentId. You can only filter on ContentDocument fields if you're filtering by LinkedEntityId.

You can't filter on the related object fields. For example, you can't filter on the properties of the account to which a file is linked. You can filter on the properties of the file, such as the title field.

Most critically,

A SOQL query must filter on one of Id, ContentDocumentId, or LinkedEntityId.

That's the one that's biting you here, and as you've discovered, there isn't a way around it. If you're aiming to remove links sharing files to specific records, for example, you'll need to do a query along the lines of

Select Id, LinkedEntityId, ContentDocumentId, IsDeleted, SystemModstamp, ShareType, Visibility 
FROM ContentDocumentLink 
WHERE ContentDocumentId IN 
     ('LITERAL_ID_ONE', 'LITERAL_ID_TWO', 'LITERAL_ID_THREE', ...)

The system just won't let you end-run around the requirement to filter on an Id or set of Ids by using a subquery. Oddly enough, you can subquery on LinkedEntityId, but it's not permitted on ContentDocumentId.

You can query your ContentDocument records separately and postprocess those query results to develop a set of specific Ids you want to query against, however.

Also important to note that if you're issuing the query through some facility other than Apex with a bound Id collection variable, your WHERE clause has a maximum length of 4,000 characters. If you have a large number of ContentDocuments whose links you would like to query, you'll need to do some batching.

I've previously shared an example of how to do this batching in a Python script.

  • Thanks David. There’s over 100k records that need to be modified, thus given the WHERE clause limit, would it be possible to have a dramatically long SOQL query in Developer Console or would it have to be executed from an Apex script? – SFExplorer Sep 30 '18 at 3:48
  • 1
    @SFExplorer See my edits - I've tried to clarify this. If you don't want to batch, you'd need to do it in Apex with a binding like SELECT ... WHERE ContentDocumentId IN :someSetOfIds. – David Reed Sep 30 '18 at 13:38
  • Thank you for linking to the Python script, looks very handy! It’s really crazy that this type of workaround needs to exist due to SOQL being so limited. This should be common functionality for developers. – SFExplorer Sep 30 '18 at 16:23

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.