0

I'm writting a query in a batch like that :

DateTime dt = DateTime.now();
DateTime trueDt = dt.addHours(2);
DateTime dtMoins1 = trueDt.addHours(-1);
String p = 'p';

String query = 'SELECT Id, StageName, CreatedDate FROM Opportunity WHERE StageName =:'+p+'AND CreatedDate <=:'+dtMoins1;

I run the batch in an anomymous window with this code (I don't think the problem come from here) :

Database.executeBatch(new myBatch());

But I got an error :

FATAL_ERROR System.QueryException: unexpected token: 'CreatedDate'

2 Answers 2

1

you missed space between "+p+'" and "AND". you can use concatenation or field binding to get values from variables. but not at same time both Should be

DateTime dt = DateTime.now();
DateTime trueDt = dt.addHours(2);
DateTime dtMoins1 = trueDt.addHours(-1);
String p = 'p';
String query = 'SELECT Id, StageName, CreatedDate FROM Opportunity WHERE StageName =\''+p+'\' AND CreatedDate <= '+dtMoins1.format('yyyy-MM-dd\'T\'hh:mm:ss\'Z\'');

you can use concatenation or field binding to get values from variables. but not at same time both

4
  • Thank you it resolve a part of my problem, because now it says "System.QueryException: unexpected token: '2017-06-06'". My query is now : 'SELECT Id, StageName FROM Opportunity WHERE StageName = :' + p +' AND CreatedDate <= :' + dtMoins1; I don't see where I could have miss a space...
    – dou
    Jun 6, 2017 at 14:55
  • 1
    Remove the colon character before your date value...
    – Adrian Larson
    Jun 6, 2017 at 14:59
  • @AdrianLarson it resolve a part of the problem too, but I got another error now : "system.QueryException: line 1:103 no viable alternative at character '<EOF>'" (it show the line where my query is)
    – dou
    Jun 6, 2017 at 15:03
  • 1
    @dou I've updated my post. That code works for me Jun 6, 2017 at 15:03
2

There is no need to use dynamic SOQL in batch Apex (unless you have to). So in your case you can avoid the quoting/concatenation clutter (and mistakes) and datetime formatting problems and get compile-time checking by using static SOQL:

DateTime dt = DateTime.now();
DateTime trueDt = dt.addHours(2);
DateTime dtMoins1 = trueDt.addHours(-1);
String p = 'p';

return Database.getQueryLocator([
        SELECT Id, StageName, CreatedDate
        FROM Opportunity
        WHERE StageName = :p
        AND CreatedDate <= :dtMoins1
        ]);
2
  • But in a batch the return type of the start method is Database.QueryLocator, so I'm not sure if I can do this
    – dou
    Jun 6, 2017 at 15:26
  • 1
    @dou My bad - I'd left the Database.getQueryLocator call out of the code; there is a signature that accepts a list of SObjects as well as one that accepts a (SOQL) string.
    – Keith C
    Jun 6, 2017 at 15:36

You must log in to answer this question.

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