From what I've read, this error should only occur when there is no WHERE clause, or when the WHERE clause isn't restrictive enough. In my case, neither is true. I am querying against a text formula field on the Campaign Member object that concatenates the contact Id and campaign Id, thus creating a unique key on each member record. Below is my code, and it's the CampaignMember query that's failing.
I've re-created verbatim one of these failed queries in the dev console. As expected, it returns one row. Could the issue have to do with querying against a formula field? I imagine since this presumably forces a broad calculation of every record's value to check the filter that this may be the problem, but am hoping to confirm before going through the effort of re-creating the formula as a logic-driven text field (ugh). Your help is appreciated!
public static void AddToCampaign (List<Contact> triggerList, Map<Id,Contact> oldMap)
{
Map<Contact,CampaignMember> contactMemberMap = new Map<Contact,CampaignMember>();
Map<Contact,String> keyMap = new Map<Contact,String>();
for (Contact c : triggerList)
{
if (c.AddToCampaign__c != null && c.AddToCampaign__c != oldMap.get(c.Id).AddToCampaign__c)// && c.AddToCampaignStatus__c != null)
{
String campaignId = c.AddToCampaign__c.substringBefore(' - ');
String status = c.AddToCampaign__c.substringAfter(' - ');
system.debug('contact: ' + c.Id + ', campaignId: ' + campaignId + ', status: ' + status);
system.debug('adding key value ' + string.valueOf(c.Id).left(15) + ' | ' + string.valueOf(campaignId).left(15) + ' to keyMap');
contactMemberMap.put(c,new CampaignMember(Status = status,ContactId = c.Id,CampaignId = campaignId));
keyMap.put(c,string.valueOf(c.Id).left(15) + ' | ' + string.valueOf(campaignId).left(15));
}
c.AddToCampaign__c = null;
}
if (!contactMemberMap.isEmpty())
{
List<CampaignMember> members = new List<CampaignMember>();
Map<String,CampaignMember> memberMap = new Map<String,CampaignMember>();
Map<String,Integer> statusRank = new Map<String,Integer>{'Sent' => 1,'Opened' => 2,'Clicked' => 3,'Replied' => 4,'Meeting Booked' => 5};
for (String k : keyMap.values())
system.debug('key: ' + k);
system.debug('executing query, map size: ' + keyMap.size());
// THIS IS THE FAILING QUERY
for (CampaignMember m : [SELECT Id, Status, MemberKey__c FROM CampaignMember WHERE MemberKey__c IN :keyMap.values()])
{
if (new Set<String>(keyMap.values()).contains(m.MemberKey__c))
memberMap.put(m.MemberKey__c,m);
}
for (Contact c : contactMemberMap.keySet())
{
String memberKey = keyMap.get(c);
CampaignMember m = contactMemberMap.get(c);
if (memberMap.containsKey(memberKey))
{
CampaignMember m2 = memberMap.get(memberKey);
if (statusRank.get(m2.Status) < statusRank.get(m.Status))
{
system.debug('new statusRank is higher, updating existing member for ' + memberKey);
m.Id = m2.Id;
members.add(m);
}
}
else
{
system.debug('creating new member for ' + memberKey);
members.add(m);
}
}
if (!members.isEmpty())
upsert members;
}
}