【发布时间】:2019-11-25 21:47:09
【问题描述】:
我想知道 DB::statement 和 DB::unprepared 查询之间出现的问题,所以显然 DB::statement 方法不适用于对列本身执行表达式的查询,如下所示:
更新标签 SET ? = ? + 2 在哪里? > ?和 user_id = ? AND tree_id = ?
这导致 SQL 如下:
更新标签 SET rgt = rgt + 2 WHERE rgt > 2 AND user_id = 1 AND tree_id = 1
^当在 mysql 解释器中使用时,这个查询工作得很好,但与 laravel 的 DB::statement 方法(它与未准备的方法 btw 一起工作)很糟糕。
这种不匹配的原因是什么?
它弹出的错误是SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax,这很奇怪,因为它的语法正确并且已经可以在mysql上正常工作。
所以语句方法是这样做的:
{
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();
});
}
虽然没有准备:
{
return $this->run($query, [], function ($query) {
if ($this->pretending()) {
return true;
}
$this->recordsHaveBeenModified(
$change = ($this->getPdo()->exec($query) === false ? false : true)
);
return $change;
});
}
我认为问题出在prepare 方法上。
在其他地方也无法查明问题的问题参考:
用户建议对高级查询使用未准备的方法?此查询尽可能基本:https://laracasts.com/discuss/channels/general-discussion/raw-queries-1?page=0
另一位用户建议使用 unprepared 而不是分解为更简单的查询:https://laracasts.com/discuss/channels/laravel/why-does-my-raw-query-not-work-inside-laravel-db?page=2
奖金问题: 此外,如果您知道任何 Eloquent 处理此查询的方法,那就太棒了! (从某种意义上说,如何通过本机、where、update 等方法处理列级表达式。)
编辑:
这个问题与How to do update query on laravel fluent using db::raw 不重复,因为它仍然涉及对列值进行硬编码。 DB::raw('column * 2')
我的问题纯粹是不做任何硬编码语句,让 laravel 做绑定。
例如:这个查询 -
DB::update(DB::raw(
'UPDATE tags SET ? = ? ? ? WHERE ? >= ? AND user_id = ? AND tree_id = ?'),
[$flag, $flag, $operator, $integer, $flag, $controlIndex, $user_id, $tree_id]
);
产生如下错误: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)
只要看看 SQL 查询:UPDATE tags SET rgt = rgt + 2 WHERE rgt >= 1 AND user_id = 1 AND tree_id = 1 - 这是完全合法的,如果放在 mysql 解释器中就可以工作!
【问题讨论】:
-
@Sahil - 我刚刚编辑了问题,请注意您链接的问题仍然涉及对列的表达式进行硬编码,特别是
DB::raw('column * 2'),有关更多上下文,请参阅问题的结尾我在其中添加了编辑部分以解决您的评论。
标签: php mysql laravel laravel-5 eloquent