Ruby on rails 在Rails中对PostgreSQL使用数组参数执行原始SQL查询

Ruby on rails 在Rails中对PostgreSQL使用数组参数执行原始SQL查询,ruby-on-rails,postgresql,Ruby On Rails,Postgresql,我希望这会奏效: 用户标识=[115431908] 查询=从用户中选择id,其中id=任何数组[$1] ActiveRecord::Base.connection.exec_queryquery,SQL,[[nil,用户ID]] 但是,这会导致异常TypeError:无法强制转换数组 在进行原始SQL查询时,除了获取连接或任何模型外,是否有任何方法可以使用数组参数,而不涉及ActiveRecord?如果要使用参数绑定,则必须将其转换为字符串,而不是直接使用数组: 用户标识=[115431908]

我希望这会奏效:

用户标识=[115431908] 查询=从用户中选择id,其中id=任何数组[$1] ActiveRecord::Base.connection.exec_queryquery,SQL,[[nil,用户ID]] 但是,这会导致异常TypeError:无法强制转换数组


在进行原始SQL查询时,除了获取连接或任何模型外,是否有任何方法可以使用数组参数,而不涉及ActiveRecord?

如果要使用参数绑定,则必须将其转换为字符串,而不是直接使用数组:

用户标识=[115431908] user\u id=user\u id.join',' 查询=从用户中选择id,其中id=任何数组[$1] ActiveRecord::Base.connection.exec_queryquery,SQL,[[nil,用户ID]] 这将导致查询SELECT id FROM users,其中id=任意数组[115431908]

如果您只是在闲逛,尝试查询,还可以放弃绑定,直接使用字符串插值:

query=从用户中选择id,其中id=任何数组[{user_id.join','}]
请记住,这将为SQL注入和类似的问题打开大门,因此我不建议对任何可以从外部访问的对象使用这种方法。

不太漂亮,但可以获得一个简单的PG::Connection连接,如下所示:

connection=ActiveRecord::Base.connection.instance\u variable\u get:@connection 不幸的是,pg gem也不十分优雅地支持数组,因此这只能让您走到一半,您必须对数组进行一些相当详细的手动编码:

用户标识=[115431908] 查询=从id=任意$1的用户中选择id params=[PG::textcoder::Array.new.encodeuser\u id] connection.exec_paramsquery,params
根据您想让它变得多么漂亮,您可以使用monkeypatch ActiveRecord::ConnectionAdapters::PostgreSQLAdapter来公开@connection,或者对其进行子类化并配置Rails以使用该子类。此外,pg gem将减少一些繁琐的工作。

首先创建一个可重用的复合类型定义,该定义描述一个整数数组:

在静态上下文中的某个地方 IntegerArray=ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.newActiveModel::Type::Integer.new.freeze 然后在查询中使用此类型:

用户标识=[115431908] 查询=从id=任意$1的用户中选择id params=IntegerArray.serializeuser_id ActiveRecord::Base.connection.exec_queryquery,MyLogLabel,[[nil,params]]
请注意,不需要直接使用PG::TextEncoder或PG::Connectionexec_参数。仍然需要使用ActiveRecord::ConnectionAdapters::PostgreSQL,因为复合类型不是后端不可知的。

这是哪个数据库?你确定你的陈述是正确的吗?也就是说,如果硬编码,从id=ANY数组[115431908]的用户中选择id是否有效?这是一个真实的例子吗?如果是这样,您可以将其更改为ActiveRecord::Base.connection.exec_queryUser.select:id.whereid:user_id.to_sql;但是,如果这只是问题的一个基本示例,我建议您研究一下。Arel是rails的底层查询汇编程序,它将允许您在代码中构建非常复杂的查询,然后您可以执行它们或将它们作为原始SQL输出到数据库_sql@hschne这是Postgres。是的,它确实有效。@engineersmnky这是一个很好的观点,但避免数据库和应用程序之间的查询生成器、模型和抽象是练习的重点。@engineersmnky如果我是从头开始编写应用程序,我肯定会这样做。但是Rails就是我所拥有的,所以这就是为什么。我认为您的第一个示例不起作用,因为它会从id=ANY数组['115431908']的用户生成查询SELECT id。也就是说,一个字符串为“115431908”的数组,而不是所需的三个整数的数组。实际上,我收回了这一点——它看起来与我的示例相同,并且定义了一个从未使用过的变量,userr_id。