【问题标题】:How to access raw SQL statement generated by update_all (ActiveRecord method)如何访问 update_all 生成的原始 SQL 语句(ActiveRecord 方法)
【发布时间】:2018-08-29 17:53:22
【问题描述】:

我只是想知道是否有办法访问为 update_all ActiveRecord 请求执行的原始 SQL。举个例子,下面举个简单的例子:

Something.update_all( ["to_update = ?"], ["id = ?" my_id] )

在 Rails 控制台中,我可以看到原始 SQL 语句,所以我猜想我可以通过某种方式访问​​它?

PS - 我对 update_all 特别感兴趣,无法将其更改为其他任何内容。

谢谢!

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 rails-activerecord


【解决方案1】:

如果您查看update_all is implemented 的方式,则不能像在关系上那样调用to_sql,因为它直接执行并返回一个整数(执行的行数)。

除了复制整个方法并更改最后一行之外,没有其他方法可以利用流程或获得所需的结果:

module ActiveRecord
  # = Active Record \Relation
  class Relation
    def update_all_to_sql(updates)
      raise ArgumentError, "Empty list of attributes to change" if updates.blank?

      if eager_loading?
        relation = apply_join_dependency
        return relation.update_all(updates)
      end

      stmt = Arel::UpdateManager.new

      stmt.set Arel.sql(@klass.sanitize_sql_for_assignment(updates))
      stmt.table(table)

      if has_join_values? || offset_value
        @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
      else
        stmt.key = arel_attribute(primary_key)
        stmt.take(arel.limit)
        stmt.order(*arel.orders)
        stmt.wheres = arel.constraints
      end

      #- @klass.connection.update stmt, "#{@klass} Update All"
      stmt.to_sql
    end
  end
end

您看到日志语句的原因是连接在执行语句时记录了这些语句。虽然您可以覆盖日志记录,但对于来自单个 AR 方法的调用实际上不可能做到这一点。

【讨论】:

  • 我在想这个 Max,感谢您的确认。
【解决方案2】:

如果你设置了RAILS_LOG_LEVEL=debug,Rails 会告诉你它执行了哪个 SQL 语句。

# Start Rails console in debug mode
$ RAILS_LOG_LEVEL=debug rails c

# Run your query
[1] pry(main)> Something.update_all( ["to_update = ?"], ["id = ?" my_id] )
SQL (619.8ms) UPDATE "somethings" WHERE id = 123 SET to_update = my_id;

# ^it prints out the query it executed

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2013-08-26
    • 2012-12-05
    • 2023-03-15
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多