如何访问 update_all 生成的原始 SQL 语句(ActiveRecord 方法)
How to access raw SQL statement generated by update_all (ActiveRecord method)
我只是想知道是否有办法访问为 update_all ActiveRecord 请求执行的原始 SQL。举个简单的例子:
Something.update_all( ["to_update = ?"], ["id = ?" my_id] )
在 rails 控制台中,我可以看到原始的 SQL 语句,所以我猜我可以通过某种方式访问它?
PS - 我对 update_all 特别感兴趣,无法将其更改为其他内容。
谢谢!
如果你看一下 update_all
is implemented 的方式,你不能像在关系上那样调用 to_sql
因为它直接执行并且 returns 是一个整数(执行的行数)。
除非复制整个方法并更改最后一行,否则无法进入流程或获得所需结果:
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 方法的调用执行此操作。
如果您设置了 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
我只是想知道是否有办法访问为 update_all ActiveRecord 请求执行的原始 SQL。举个简单的例子:
Something.update_all( ["to_update = ?"], ["id = ?" my_id] )
在 rails 控制台中,我可以看到原始的 SQL 语句,所以我猜我可以通过某种方式访问它?
PS - 我对 update_all 特别感兴趣,无法将其更改为其他内容。
谢谢!
如果你看一下 update_all
is implemented 的方式,你不能像在关系上那样调用 to_sql
因为它直接执行并且 returns 是一个整数(执行的行数)。
除非复制整个方法并更改最后一行,否则无法进入流程或获得所需结果:
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 方法的调用执行此操作。
如果您设置了 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