【问题标题】:User-defined MySQL variables in Laravel 3?Laravel 3 中用户定义的 MySQL 变量?
【发布时间】:2013-04-25 12:13:01
【问题描述】:

我想使用用户定义的变量更新一组具有序号的 MySQL 记录的“排名”。以下查询通过 MySQL 命令行运行良好:

SET @rank:=0; UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=4 ORDER BY score DESC

但如果我尝试使用 Laravel 将其作为 Fluent 查询运行,则会失败。

DB::query("SET @rank:=0; UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=4 ORDER BY score DESC");

错误信息:

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 'UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=4 ORDER BY' at line 1

SQL: SET @rank:=0; UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=4 ORDER BY score DESC

Bindings: array (
)

[已解决]

DB::raw() 来救援!以下作品:

DB::query(DB::raw("SET @rank:=0"));
DB::query("UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=4 ORDER BY score DESC");

【问题讨论】:

  • +1。很有意思。我也有兴趣找到这个问题的答案。
  • 重点是这不是一种说法,而是两种说法。从一个查询中设置用户变量,然后使用相同的数据库连接,运行您的更新。
  • 我试过了。尝试仅运行“SET @rank:=0”查询会导致以下错误:“方法 [] 未在 Query 类上定义。”
  • @JamieTibbetts 你能提供那个错误的堆栈跟踪吗?
  • DB::query("SET @rank:=0") 的堆栈跟踪太长,无法放入评论,但这是它的屏幕截图:link

标签: mysql laravel


【解决方案1】:

不可能在一个查询中执行多个语句。 Laravel 在后台使用 PDO 来防止这种情况发生。您可以尝试通过 2 个查询来调用它,因为 @rank 在连接期间应该可用。

DB::query("SET @rank:=0");
DB::query("UPDATE scores SET rank=@rank:=@rank+1 WHERE game_id=? ORDER BY score DESC", array(4));

【讨论】:

  • 其实PDO在v5.3切换到PHP原生的MySQL驱动后就已经支持批处理语句了。
  • 我试过了。它也不起作用。第一个查询抛出错误:“方法 [] 未在 Query 类上定义。”
  • 这个解决方案非常接近。第一个查询只需要使用 DB::raw()。例如DB::query(DB::raw("SET @rank:=0"));
  • 在多条语句中执行时是否存在竞争条件?例如另一个进程同时执行并更改@rank
  • @VladVinnikov 我不知道我是否诚实。我相信像这样的变量是每个连接的——所以如果连接被正确池化,那么它应该没有这样的问题。如果你想在更新的 Laravel 中运行它,你可以使用事务来加强它。
猜你喜欢
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多