我需要一个ID数组传递到我的原始的SQL查询是这样的:
select offers.* from offers where id in (1,2,3,4,5)
真正的查询包括大量的连接和聚合功能,并且不能使用阿雷尔表达式或类似Offer.where(id: [...])
ActiveRecord的模型方法来写。我在寻找确切地了解如何在原始查询中使用绑定变量。
相反,内插ID添加到字符串我想使用绑定变量是这样的(伪代码):
ActiveRecord::Base.connection.select_all("select offers.* from offers where id in (:ids)", {ids: [1,2,3,4,5]})
但是,我找不到任何解决方案来执行此。从this票我得在与following例如ActiveRecord的代码相关的测试用例评论:
sub = Arel::Nodes::BindParam.new
binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
sql = "select * from topics where id = #{sub.to_sql}"
@connection.exec_query(sql, "SQL", binds)
我试过这种方法,但它没有工作可言,我的“?”没有实际值替换。
我使用Rails 5.1.6和MariaDB的数据库。
你可以在一个更简单的方式与arel
这样做纯粹。 (此外,它使得代码更易于维护比SQL字符串)
offers = Arel::Table.new('offers')
ids = [1,2,3,4,5]
query = offers.project(Arel.star).where(offers[:id].in(ids))
ActiveRecord::Base.connection.exec_query(query.to_sql)
这将导致以下SQL
SELECT
[offers].*
FROM
[offers]
WHERE
[offers].[id] IN (1,2,3,4,5)
当执行与通常是最容易通过调用ActiveRecord::Result
应对每生成的行会变成to_hash
的Hash
您将收到{column_name => value}
对象
但是,如果您使用的是轨道和Offer
是一个真正的模型,则:
Offer.where(id: ids)
将导致相同的查询,并且将返回ActiveRecord::Relation
对象的Offer
集合通常更理想是。
更新
好像你需要启用prepared_statements
中才能使用绑定参数,可以它可以这样做mysql2(mariadb
):
default: &default
adapter: mysql2
encoding: utf8
prepared_statements: true # <- here we go!
正如你在上次的代码exec_query
忽略bind_params
如果prepared_statements
被关闭(这似乎是为mysql2
适配器默认)看到。