【问题标题】:ActiveRecord appends 'AND (1=0)' to end of queriesActiveRecord 将“AND (1=0)”附加到查询末尾
【发布时间】:2014-11-07 03:14:07
【问题描述】:

我一直在 Rails 控制台中尝试让事情正常工作,但我注意到我的一个查询在不应该返回 nil 时一直返回。在查看生成的 SQL 查询时,我注意到它每次都附加了AND (1=0)。这有点烦人,我不知道为什么会这样。

注意:使用actable gem。

重现步骤:

(连接到rails控制台中的表后)

2.1.2 :xxxx > @parent = Parent.take
Parent Load (38.1ms)  SELECT  `parents`.* FROM `parents`  LIMIT 1
 => #<Parent id: 37, ...>

2.1.2 :xxxx > @child = Child.where(id: @parent.actable_id)
SQL (0.7ms)  SELECT `childs`.`id` AS t0_r0, `childs`.`attribute` AS t0_r1, FROM `childs`
...
LEFT OUTER JOIN `parents` ON `parents`.`actable_id` = `childs`.`id` AND `parents`.`actable_type` = 'child type' WHERE `childs`.`id` = 20 AND (1=0)
 => #<ActiveRecord::Relation []>

为什么会这样?如何让它停止?

【问题讨论】:

  • 我注意到 Rails 为这个查询做了这个:User.where(:id =&gt; []),因为你不能在 SQL 中写 SELECT * FROM users WHERE id in ()。所以我想这是它知道不会返回任何内容但不能用 SQL 表达的查询的方法。
  • @MaxGabriel 这就是我的答案。也许把它作为答案而不是评论?
  • @jgraft 好主意,我按照你的建议做了这个答案。

标签: mysql ruby-on-rails activerecord ruby-on-rails-4 rails-console


【解决方案1】:

当您查询值在空数组中的列时,Rails 将生成类似AND (1=0) 的 SQL:

Child.where(id: [])

直观地说,您会期望生成像SELECT * FROM children WHERE id IN () 这样的SQL,但() 实际上并不是有效的SQL。但是,由于没有行会匹配该查询,Rails 通过生成一个同样不返回任何行的等效查询来解决这个问题:

SELECT * FROM children WHERE 1=0;

【讨论】:

  • 谢谢!这个答案帮助我解决了同样的困惑!太糟糕了,它从未被接受为正确答案。
  • @alex0112 你会考虑接受这个答案吗?
  • 如果您指定空哈希值,这似乎也会发生 Child.joins(:parent).where(:parents => {})
  • 感谢您的即时澄清,我已经想知道它来自哪里,但是快速的谷歌搜索可能为我节省了几个小时,我不明白的是,如果 Rails 实际执行查询(针对DB)当它知道它不会返回任何行时,为什么还要运行它呢?
  • 我不确定,但想法是:1)不返回任何内容的查询可能是子查询,它是实际返回结果的更大查询的一部分,或以某种方式修改数据库状态 2 ) 它增加了实现的复杂性 3) 对于开发人员来说,数据库查询实际上并没有命中数据库可能是出乎意料的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2017-06-15
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多