Q: Silverstripe SQL Logic I am trying to run a query but something strange happens:
$return = MyCustomPage::get()->where(
    " MyCustomPage.ID IN(" . implode(',', $MyCustomPageIds) . ")"
)->limit(2);

This return an error becasue the query it's trying to get data from MyCustomPage_Live instead of MyCustomPage .
This logic keeps like changing, sometimes it get from one table sometimes from another, and I need to specify the table name inside the query (ex. MyCustomPage.ID or MyCustomPage_Live.ID )
Is there a better way to to this or any solution ?

A: You should try to avoid raw SQL queries as much as possible and leverage the SilverStripe ORM instead.
So to achieve the same you did with your where statement, but by using the ORM you would write:
$return = MyCustomPage::get()->byIDs($MyCustomPageIds)->limit(2);

This will also automatically read from the current stage. If you need to force a stage to read from, you can use something like:
// replace 'Live' with 'Stage' to read from stage. 
Versioned::set_stage('Live'); 

In these cases it's also good practice to store the current stage first and restore it after.
$currentStage = Versioned::get_stage(); 
Versioned::set_stage('Live');

// Do your thing…

Versioned::set_stage($currentStage);


A: You don't need a where statement to do this, you could do something along the lines of CustomPage::get()->filter(['ID' => $CustomPageArray])->limit(2) instead. Arrays as a second argument in SilverStripe are treated as an IN type of query. Using a filter will also automatically solve the versioning problem which is what you run in to.
If you really need to use a where, something like this would help:
$extra = '';
if (Versioned::current_stage() == 'Live') {
     $extra = '_live'
}
Page::get()->where('MyFilter' . $extra . '.ID' IN implode(',', $CustomIds));

enter code here
(Excuse any syntax errors ;) )
