I have a batch job that process 100 records at a time. During this process it attempts to find and assign ownership of the record to a given user based on different criteria. My problem is that occasionally a user defined in the matching table may no longer be active or set to have access to a record. So even though it allows me to set the owner to the user, it crashes during the update because the new owner of one of the records doesn't have read access.

You can check multiple records at a time, but for only one user.

SELECT RecordId, HasEditAccess FROM UserRecordAccess WHERE UserId = [single ID] AND RecordId = [single ID] or [set of record ids]

But I need to check multiple users and multiple records. For example I need to check that User A has access to record A and User B has access to record B and User C has access to record C. So I would have to run the above query 3 times to check all 3. Which is fine, but I may have up to 100 pairs to check. So 100 queries is not possible. Does anyone know of a way to check multiple records and users at the same time, with one query?

1 Answer 1


If the user doesn't have "read" access to the object, checking UserRecordAccess probably won't help you. They do not need read access to the record that is being assigned to them, so long as the process that's running is running in system mode or by a user with modify all data permission for the object. UserRecordAccess isn't designed for "bulk" checking of user permissions, but rather for checking if a single user has access to a single record, usually for displaying an error on a Visualforce page and/or changing the UI to reflect their ability to edit/delete a record.

Instead, I'd turn this around and instead just let the system tell you what's wrong. Example code follows:

Database.SaveResult[] results = Database.update(records, false);
for(Integer index = 0, size = results.size(); index < size; index++) {
    if(!results.isSuccess()) {
        Database.Error[] errors = results[index].getErrors();
        for(Integer eIndex = 0, eSize = errors.size(); eIndex < eSize; eIndex++) {
            StatusCode c = errors[eIndex].getStatusCode();
            if(c == StatusCode.INACTIVE_OWNER_OR_USER) {
                // Handling inactive owner
            } else if(c == StatusCode.CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY) {
                // Handle sharing violation
            // You may need other status codes, so please experiment

The full list of Exception Codes is found in the documentation.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .