function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Andy Kallio 7Andy Kallio 7 

SOQL In Operator not working as expected

Hello. I am trying to use the invocableMethod annotation to pass some ids from a flow to the method that will return a list of custom Sobjects.

For some reason the soql is only finding the first record, and I don't see why. Posted here is the class and a debug log. Thanks for any help!!
 
public with sharing class getCampaigns_Flow {
    
    @invocableMethod
    public static list<list<Campaign__c>> getCampaigns(list<string> campaignIds) {
        system.debug('campaignIds: '+campaignIds);
        list<list<Campaign__c>> varCamps = new list<list<Campaign__c>>();
        List<string> varIds = campaignIds[0].split(';');
        system.debug('varIds: '+varIds);
        list<Campaign__c> camps = [select Id,
                                    Target_Audience__c,
                                    Geographic_Targeting__c,
                                    Search_Keywords__c,
                                    Creative_Versions_Per_Flight__c
                                    from Campaign__c
                                    where Id In :varIds];
        varCamps.add(camps);
        system.debug('camps: '+camps);
        system.debug('varCamps: '+varCamps);
        return varCamps;
    }
}
User-added image
 
v varaprasadv varaprasad
Hi Andy,


Try this : 
 
public with sharing class getCampaigns_Flow {
    
    @invocableMethod
    public static list<list<Campaign__c>> getCampaigns(list<string> campaignIds) {
        system.debug('campaignIds: '+campaignIds);
        list<list<Campaign__c>> varCamps = new list<list<Campaign__c>>();
        //List<string> varIds = campaignIds[0].split(';');
        //system.debug('varIds: '+varIds);
        list<Campaign__c> camps = [select Id,
                                    Target_Audience__c,
                                    Geographic_Targeting__c,
                                    Search_Keywords__c,
                                    Creative_Versions_Per_Flight__c
                                    from Campaign__c
                                    where Id In :campaignIds];
        varCamps.add(camps);
        system.debug('camps: '+camps);
        system.debug('varCamps: '+varCamps);
        return varCamps;
    }
}
Hope this helps you!
If my answer helps resolve your query, please mark it as the 'Best Answer' & upvote it to benefit others.


Salesforce Freelance Consultant/Developer/Administrator/Trainer
@For Salesforce Project Support: varaprasad4sfdc@gmail.com

Salesforce latest interview questions and training videos :
https://www.youtube.com/channel/UCOcam_Hb4KjeBdYJlJWV_ZA?sub_confirmation=1


Thanks,
V Varaprasad
Email: varaprasad4sfdc@gmail.com


 
SANDEEP CHITTINENISANDEEP CHITTINENI
public with sharing class getCampaigns_Flow {
    
    @invocableMethod
    public static list<list<Campaign__c>> getCampaigns(list<string> campaignIds) {
        system.debug('campaignIds: '+campaignIds[0]);
        system.debug('campaignIds: '+campaignIds[1]);
        system.debug('campaignIds: '+campaignIds[2]);
        list<list<Campaign__c>> varCamps = new list<list<Campaign__c>>();
        //List<string> varIds = campaignIds[0].split(';');
        //system.debug('varIds: '+varIds);
        list<Campaign__c> camps = [select Id,
                                    Target_Audience__c,
                                    Geographic_Targeting__c,
                                    Search_Keywords__c,
                                    Creative_Versions_Per_Flight__c
                                    from Campaign__c
                                    where Id In :campaignIds];
        varCamps.add(camps);
        system.debug('camps: '+camps);
        system.debug('varCamps: '+varCamps);
        return varCamps;
    }
}

You can directly pass the argument "campaignIds" in to the SOQL Query.
I have set debugs for the list on line 5,6&7. see the logs how data is coming.
In the above code, on line 9 you are just passing only one record Id by using index "campaignIds[0]" to the list "varIds". That is why your query is returning one record.
But now you can above code and query as you are expecting.
Mark it is a best answer. If it helps you.
Andy Kallio 7Andy Kallio 7
Hi. Thanks for the responses but this doesn't work. campaignIds.length() = 1  It only has one item, and you will notice in my debug for campaigndIds that they are semicolon separated. This is because they are coming from a multi-select in the flow. It's a strange behavior of flow that I have seen discussed in other posts which is where I go the idea for the creating the varIds variable. And if you look at the debug for that var you can see that is now a comma separated list, and I have tested with a different debug (not the one in my post) to confirm that list.size() is as expected. So, still not sure why the query would only be getting the first Id in the list using the IN operator. 
Andy Kallio 7Andy Kallio 7

I have been looking a little further at the docs on the comparison operators.  https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_comparisonoperators.htm

It says 'The values for IN must be in parentheses. String values must be surrounded by single quotes.' I noticed in my debugs that the values were not in quotes. So, I tried the following code to put get them in quotes before using them in the code. I also tried the = operator because it seems to be interchangeable with IN but that doesn't work either. And you will notice I'm using a set, but I have also tried that set as a list. None of this works. Actually, it's worse now because the query finds no results with the quotes. 
 

public with sharing class getCampaigns_Flow {
    
    @invocableMethod
    public static list<list<Campaign__c>> getCampaigns(list<string> campaignIds) {
        system.debug('campaignIds: '+campaignIds);
        
        list<list<Campaign__c>> varCamps = new list<list<Campaign__c>>();
        list<string> varIds = campaignIds[0].split(';');
        set<string> varIdSet = new set<string>();
        
        system.debug('campaignIds0: '+campaignIds[0]);
        system.debug('varIds: '+varIds+' '+varIds.size());
        
        for(string varId : varIds) {
            varId = '\''+varId+'\'';
            varIdSet.add(varId);
        }
        system.debug('varIdSet: '+varIdSet);
        
        list<Campaign__c> camps = [select Id,
                                    Target_Audience__c,
                                    Geographic_Targeting__c,
                                    Search_Keywords__c,
                                    Creative_Versions_Per_Flight__c
                                    from Campaign__c
                                    where Id = :varIdSet];
        varCamps.add(camps);
        
        system.debug('camps: '+camps);
        system.debug('varCamps: '+varCamps);
        
        return varCamps;
    }
}

 
Andy Kallio 7Andy Kallio 7
Ok. here are my next thoughts. I tried altering the query to search for a hardcoded string. For example:
where Id IN ('a179000000X9hOtAAJ','a179000000X9hPwAAJ')

And this works exactly as expected.

So there must be something wrong with how I am constructing the various bind variables that I have tried. 
So, then I tried just creating a string to bind instead of a list. And, I get the following 'IN operator must be bound to an iterable variable'.  I understand the error. This seems to be a dead end. Just want to point it out to save anybody else the time of trying it. 

Here is that code. 
 
public with sharing class getCampaigns_Flow {
    
    @invocableMethod
    public static list<list<Campaign__c>> getCampaigns(list<string> campaignIds) {
        system.debug('campaignIds: '+campaignIds);
        
        list<list<Campaign__c>> varCamps = new list<list<Campaign__c>>();
        list<string> varIds = campaignIds[0].split(';');
        set<string> varIdSet = new set<string>();
        string varIdString = '';
        
        system.debug('campaignIds0: '+campaignIds[0]);
        system.debug('varIds: '+varIds+' '+varIds.size());
        
        for(string varId : varIds) {
            varId = '\''+varId+'\'';
            varId.trim();
            //varIdSet.add(varId);
            varIdString += varId;
            
        }
        varIdString = '('+varIdString+')';
       // system.debug('varIdSet: '+varIdSet);
        
        list<Campaign__c> camps = [select Id,
                                    Target_Audience__c,
                                    Geographic_Targeting__c,
                                    Search_Keywords__c,
                                    Creative_Versions_Per_Flight__c
                                    from Campaign__c
                                    where Id IN :varIdString];
        varCamps.add(camps);
        
        system.debug('camps: '+camps);
        system.debug('varCamps: '+varCamps);
        
        return varCamps;
    }
}

 
Valeriya KimValeriya Kim
Hello Andy, hope you've already figured this one out.
The string that is comming from visual flow should be split by semicolon with a whitespace
List<string> varIds = campaignIds[0].split('; ');

 
Andy Kallio 7Andy Kallio 7
oh wow. I ended up finding a different way to do it within flow. Your suggestion seems like it could work though....wish I had thought of it.