You need to sign in to do that
Don't have an account?

System.QueryException : Unexpected token '('
Hi,
I am having trouble getting this query working in a batchable class.
In my start method when I use the following query :
String query = 'Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN: '+ accTypesToInclude ;
return Database.getQueryLocator(query);
I am getting the error :
System.QueryException: unexpected token: '('
Any ideas whats wrong
Thanks
@rahulsharma,
As I stated previously, this dynamic string binding only occurs in a Database method, such as Database.getQueryLocator() or Database.query(). I shall provide a demonstration from my logs to prove that the system does work as I have described.
First, I shall provide a sample Dynamic Apex Code, such as I described in my previous response.
Here is the Execute Anonymous code that I used:
Having executed this code, the result returns three records, two named 'test', and one named 'test me'. This is despite the fact that used only dynamic colon binding and did not use any fancy tricks to achieve these results.
Here is the output from my example code:
As you can see, the first red line in my demonstration proves that the string has been unaltered, using only a dynamic apex binding variable as I outlined previously. No escaped quotes, parenthesis, mathematical operators or functions were harmed in the making of this string.
Slightly later, you can determine that the string is passed into the Database.query method, and it still looks the same as the variable. The magenta line immediate thereafter shows that the system returned three records, even though "test" and "test me" were never explicitly put into the string. I did not have to count commas, use any special quotes, or parenthesis, and the system was still able to single out those three records to my precise specification.
Dynamic Apex is meant to be as easy and secure as possible, and given that the most likely attack vector for SOQL injection is incorrect character escapes while using Dynamic Apex, it makes sense that parameter binding working on these functions. This design is in place to reduce the risks of users typing in a "search term" of ') or name <> ', which if care is not exercised, might well crash your script or expose data they shouldn't see.
Please try this for yourself so you can understand how parameter binding can be used to create dynamic queries quickly and easily.
All Answers
PXForce:
you can't add the set of ids to the string query and have apex cast it for you into the proper format.
you need to get you string to look like this.
in order to do that you have to loop through your set of Ids and put them into a string.
accTypesToInclude is already a list of ids...anyways i got that working ...but when I use NOT IN: instead of IN: it gives me System.Exception unknown token ':'
any ideas why?
yes don't use the ':' in the string, you don't need it.
Actually, you can use that syntax, but the variable has to be in the string. Do this:
Dynamic Apex supports variable binding directly. Just be sure that the variable is in the scope of the dynamic query function (in this case, getQueryLocator).
Hello PXForce,
1)I just have doubt that u have to use ID instead of type while filtering query,if you are filtering it as type(string).
2)your Id must be in string in that query,
Try this:
String query = 'Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN \''+ accTypesToInclude+'\'' ;
Hope this helps.
If you don't use variable binding, then you must use parenthesis, just as in SQL.
Hello,
i just noticed that,
if u debug this :
Id accTypesToInclude ='00190000004Ww8A';
String query = 'Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN :accTypesToInclude';
system.debug(query);
you'll get :
DEBUG|Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN :accTypesToInclude
and if u debug this string:
Id accTypesToInclude ='00190000004Ww8A';
String query = 'Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN \''+ accTypesToInclude+'\'' ;
system.debug(query);
you'll get :
Select a.Id, a.Name, a.OwnerId ,(Select Id, OwnerId From Contacts) from Account a Where a.Type IN '00190000004Ww8AAAS'
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
I took static Id only for Explanation
@rahulsharma,
As I stated previously, this dynamic string binding only occurs in a Database method, such as Database.getQueryLocator() or Database.query(). I shall provide a demonstration from my logs to prove that the system does work as I have described.
First, I shall provide a sample Dynamic Apex Code, such as I described in my previous response.
Here is the Execute Anonymous code that I used:
Having executed this code, the result returns three records, two named 'test', and one named 'test me'. This is despite the fact that used only dynamic colon binding and did not use any fancy tricks to achieve these results.
Here is the output from my example code:
As you can see, the first red line in my demonstration proves that the string has been unaltered, using only a dynamic apex binding variable as I outlined previously. No escaped quotes, parenthesis, mathematical operators or functions were harmed in the making of this string.
Slightly later, you can determine that the string is passed into the Database.query method, and it still looks the same as the variable. The magenta line immediate thereafter shows that the system returned three records, even though "test" and "test me" were never explicitly put into the string. I did not have to count commas, use any special quotes, or parenthesis, and the system was still able to single out those three records to my precise specification.
Dynamic Apex is meant to be as easy and secure as possible, and given that the most likely attack vector for SOQL injection is incorrect character escapes while using Dynamic Apex, it makes sense that parameter binding working on these functions. This design is in place to reduce the risks of users typing in a "search term" of ') or name <> ', which if care is not exercised, might well crash your script or expose data they shouldn't see.
Please try this for yourself so you can understand how parameter binding can be used to create dynamic queries quickly and easily.
Thank you very much sdfcfox for making things very clear and simple..
@sfdcfox
I ran into this same issue.
Where do i get the Database.query class?
Is there a Jar file or WSDL that it comes from?
I cant seem to see it under any JAVA import statements.
Any help is greatly appreciated.
Thanks
It's part of the system library for Apex Code. There is no JAR or WSDL, because we're talking about Apex Code, not Java.
i'm getting this error "Calculation error on quote Q-05208: System.QueryException: invalid ID field: null" please guide me why im getting this error.
Thanks & Regards