如何逃脱? (问号)运算符在 Rails 中查询 Postgresql JSONB 类型

Posted

技术标签:

【中文标题】如何逃脱? (问号)运算符在 Rails 中查询 Postgresql JSONB 类型【英文标题】:How to escape the ? (question mark) operator to query Postgresql JSONB type in Rails 【发布时间】:2015-08-18 04:38:15 【问题描述】:

我正在使用 Rails 4.2 和 Postgres 9.4 来尝试新的 JSONB 数据类型。我的数据库中的一个 JSONB 列包含一个数组,我希望能够查询该数组包含某个值的记录。我想出了如何使用新的 JSONB“问号”(“包含”)运算符来做到这一点,如此处所述: http://www.postgresql.org/docs/9.4/static/functions-json.html

所以在原始 SQL 中,我可以让它像这个例子一样工作:

SELECT * FROM people WHERE roles ? '32486d83-4a38-42ba-afdb-f77ca40ea1fc';

但是我看不到通过 ActiveRecord 从 Rails 中执行此查询的任何方法。我尝试使用“where”方法进行原始查询,如下所示:

Person.where("roles ? ?", "32486d83-4a38-42ba-afdb-f77ca40ea1fc")

但是由于问号是用于替换参数的特殊字符,所以我得到这个错误:

ActiveRecord::PreparedStatementInvalid:绑定变量的数量错误 (1 比 2)在:角色? ?

我想我需要一种方法来逃避“?”字符,因为我希望它从字面上通过。我试过了 \?和 ??没有运气。 任何帮助表示赞赏!

【问题讨论】:

试试这个Person.where("roles ? (?)", "32486d83-4a38-42ba-afdb-f77ca40ea1fc") Person.where("roles ? :name", name: "32486d83-4a38-42ba-afdb-f77ca40ea1fc") @R_O_R 您知道您可以使用to_sql 来查看查询产生的结果,而无需实际运行查询。 @muistooshort 我检查了Person.where("roles ? :name", name: "32486d83-4a38-42ba-afdb-f77ca40ea1fc") 是正确的方法...我使用to_sql 进行了测试。但无法回答,因为它标记为 dup一个错误的语言答案。 @R_O_R -- 我测试了你的第二个答案,它确实有效!非常感谢。如果有人没有错误地将我的问题标记为重复,我希望我能接受你的回答。 【参考方案1】:

你应该这样称呼它:

Person.where("roles ? :name", name: "32486d83-4a38-42ba-afdb-f77ca40ea1fc")

【讨论】:

【参考方案2】:

一种解决方法。运行此查询以找出您的运算符映射到的函数:

SELECT 
  oprname, 
  oprcode || '(' || format_type(oprleft,  NULL::integer) || ', ' 
                 || format_type(oprright, NULL::integer) || ')' AS function
FROM pg_operator 
WHERE oprname = '?';

它产生

oprname  function
?        jsonb_exists(jsonb, text)
?        exist(hstore, text)

现在在查询中使用函数而不是运算符:

Person.where("jsonb_exists(roles, ?)", "32486d83-4a38-42ba-afdb-f77ca40ea1fc")

【讨论】:

很高兴知道这一点。谢谢!如果你想要一个所有 JSONB操作符的列表,你可以查询WHERE oprcode::text like 'jsonb_%';

以上是关于如何逃脱? (问号)运算符在 Rails 中查询 Postgresql JSONB 类型的主要内容,如果未能解决你的问题,请参考以下文章

插入和删除查询是不是可以从锁定等待超时中逃脱?

Hibernate在SQL查询中显示问号[重复]

查询 Mongoid/rails 3 中的嵌入对象(“低于”、Min 运算符和排序)

如何在 hive 查询的准备语句中转义?(问号)?

在 C# 中,两个问号一起意味着啥?

在 AFNetworking 3 GET 请求中删除查询末尾的问号