I wanna know the problem that is arising between DB::statement and DB::unprepared queries, So apparently DB::statement methods are not functioning with queries that do expressions on columns itself, something like this:
UPDATE tags SET ? = ? + 2 WHERE ? > ? AND user_id = ? AND tree_id = ?
This results into SQL as:
UPDATE tags SET rgt = rgt + 2 WHERE rgt > 2 AND user_id = 1 AND tree_id = 1
^This query when used within mysql interpreter works absolutely fine but shits brick with laravel's DB::statement method (it works fine with unprepared method btw).
Whats the reason behind this mismatch?
The error it pops up with is SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax
which is weird because its correct syntax and already works fine with mysql.
So the statement method is doing this:
{
return $this->run($query, $bindings, function ($query, $bindings) {
if ($this->pretending()) {
return true;
}
$statement = $this->getPdo()->prepare($query);
$this->bindValues($statement, $this->prepareBindings($bindings));
$this->recordsHaveBeenModified();
return $statement->execute();
});
}
While the unprepared one:
{
return $this->run($query, [], function ($query) {
if ($this->pretending()) {
return true;
}
$this->recordsHaveBeenModified(
$change = ($this->getPdo()->exec($query) === false ? false : true)
);
return $change;
});
}
I think the issue is arriving at the prepare
method.
Issue References elsewhere that couldn't pinpoint the problem either:
User suggesting that unprepared method should be used for the advanced queries? This query is as basic as it can possibly get: https://laracasts.com/discuss/channels/general-discussion/raw-queries-1?page=0
Another user suggesting to use unprepared instead of breaking down to simpler queries: https://laracasts.com/discuss/channels/laravel/why-does-my-raw-query-not-work-inside-laravel-db?page=2
Bonus Question: Moreover, if you know any Eloquent way of handling this query, it'd be awesome! (In the sense how to handle column level expressions via native, where, update, etc methods.)
Edit:
This question is not a duplicate to How to do update query on laravel fluent using db::raw because it still involves hardcoding the column value. DB::raw('column * 2')
My question is purely from not doing any hardcoding statement and let laravel do the bindings.
For example: This query -
DB::update(DB::raw(
'UPDATE tags SET ? = ? ? ? WHERE ? >= ? AND user_id = ? AND tree_id = ?'),
[$flag, $flag, $operator, $integer, $flag, $controlIndex, $user_id, $tree_id]
);
produces error as follows: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? = ? ? ? WHERE ? >= ? AND user_id = ? AND tree_id = ?' at line 1 (SQL: UPDATE tags SET rgt = rgt + 2 WHERE rgt >= 1 AND user_id = 1 AND tree_id = 1)
Just look at the SQL query: UPDATE tags SET rgt = rgt + 2 WHERE rgt >= 1 AND user_id = 1 AND tree_id = 1
- This is completely legit and works if put in mysql interpreter!