1

I have about 1200 orphan Contacts (not related to any Account). I want to delete these Contacts, however they have related Opportunities. So obviously, I need to first delete these opportunities.

I wrote this code to get the Opportunity Id's, so then i can mass delete these opportunities with Data Loader.

However, I am getting 0 records in the opportunity list when I put the condition to get only contact id's from the set. What could i be doing something wrong?

List<Contact> con = [SELECT AccountId,AssistantPhone,CreatedDate,Email,FirstName,HomePhone,Id,LastName,MobilePhone,Name,OtherPhone,OwnerId,Phone
                 FROM Contact 
                 Where AccountId = Null AND Email = Null AND HomePhone = Null AND MobilePhone = Null AND OtherPhone = Null AND Phone = NULL];

System.debug('Number of orphan contacts: ' +con.size());   **// 1200, that is correct**


set<string> conid = new set<string>();
 if(conid.size()>0 && conid !=null){
    for (Contact c : con){
        conid.add(c.id);

    }
 }

System.debug('Collecting contact Ids in a Set: ' +con.size());    **// 1200, correct so far** 

List<Opportunity> opps =  [SELECT ID, AccountId,Account_RouteOne_ID__c,CloseDate,ContactId,CreatedDate,DM_Contact__r.id,IsClosed,IsPrivate,Name,OwnerId,RecordTypeId,StageName
                       FROM Opportunity 
                       WHERE DM_Contact__c IN: conid ];        // DM_Contact__c is a lookup to contact   DM_Contact__c = '003E000000y0VY7IAM'


system.debug ('opps size is: ' +opps.size());   **// 0, incorrect**

list<id> oppsidToDelete = new list <id>();
   for (Opportunity o :opps){

      oppsidToDelete.add(o.id);

   }
  • 1
    If you go to one of those Contact records, do you see any Opportunities in a related list? – Drew Kennedy Oct 16 '19 at 16:29
  • 1
    Your query looks good, are you sure about the field that on the opportunity object? Also, you don't need to get the Ids by going through a loop. You should be able to do in : con. Also if you're writing the apex, you can just do delete opps; – Jason Hardy Oct 16 '19 at 16:42
1

Your problem is here:

set<string> conid = new set<string>();
 if(conid.size()>0 && conid !=null){  // this will always be false!!
    for (Contact c : con){
        conid.add(c.id);

    }
 }

you want:

set<Id> conid = new set<Id>();
for (Contact c: con) {
    conId.add(c.Id);
}

You can actually rewrite this whole class in two statements

List<Contact> orphanContacts = [SELECT Id
             FROM Contact 
             Where AccountId = Null AND Email = Null AND 
                   HomePhone = Null AND MobilePhone = Null AND OtherPhone = Null AND 
                   Phone = NULL];
delete [SELECT ID
           FROM Opportunity 
           WHERE DM_Contact__c IN  // assumes DM_Contact__c is a lookup field
             :orphanContacts];

This is because bind variables of list of sobjects will use their Ids where compared to a field of ID type

or in one statement using a semi-join

delete [SELECT ID
           FROM Opportunity 
           WHERE DM_Contact__c IN  // assumes DM_Contact__c is a lookup field
             (SELECT Id
               FROM Contact 
               WHERE AccountId = Null AND Email = Null AND 
                   HomePhone = Null AND MobilePhone = Null AND OtherPhone = Null AND 
                   Phone = NULL)];
| improve this answer | |
  • thank you for helping and teaching me. – user4947 Oct 16 '19 at 17:39
  • @user4947 - no problem; I learned a ton from others on this site; just passing it forward – cropredy Oct 16 '19 at 17:45

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.