我有一个Rails应用程序和一个包含像["manager", "engineer"]
等数组的列,以及这样的where语句:
where("? = ANY roles", query)
如果我传递单个值进行查询,可以找到。我希望能够传递多个值。我做了一些谷歌搜索,找到了一个简单的解决方案:
where("? && roles", query )
除非我传递类似"['admin', 'guest']"
的内容,否则会收到此错误:
PG::InvalidTextRepresentation: ERROR: malformed array literal: "['admin', 'guest']"
LINE 1: .... $1 AND ('[''admin'...
^
DETAIL: "[" must introduce explicitly-specified array dimensions.
我怀疑有一些奇怪的引用逃避问题,但我无法弄清楚。这些错误消息会产生一堆JSON Q& As,但没有任何解决方案可以跳出来。
更新
我似乎总是在发布问题后找到线索 - 我试过了:
where("'{guest, admin}'::text[] && roles", query )
并且它有效 - 我仍然不知道为什么,但确实如此。现在我看不到如何让?
回到那里,所以我可以搜索它。
更新2
我在下面给出了第一个答案并进行了一些重构,以获得我认为简单优雅的解决方案:
where("'{#{roles}}'::text[] && roles")
这样我就可以将一个简单的文本字符串传递给我的应用程序助手,这个where子句就在这里。它处理单个和多个查询。
答案 0 :(得分:3)
对于数组,使用数组构造函数语法几乎总是更好。来自fine manual:
<强> 4.2.12。阵列构造函数
数组构造函数是一个表达式,它使用其成员元素的值构建数组值。一个简单的数组构造函数包含关键字
ARRAY
,左方括号[
,数组元素值的表达式列表(用逗号分隔),最后是右方括号{{1} }。例如:]
ActiveRecord会将占位符的数组值扩展为逗号分隔列表,这正是括号内SELECT ARRAY[1,2,3+4];
array
---------
{1,2,7}
(1 row)
语法所需的内容。所以你要说:
array[...]
如果where('array[?] && roles', query)
是单个值,这甚至是正确的。
就更新而言,这是:
query
是一个字符串文字('{guest, admin}'::text[]
),后跟一个类型转换('{guest, admin}'
)到一个文本数组(::
)。字符串中的text[]
语法是另一种形式的数组,易于阅读但是正确构建的麻烦; fine manual也涵盖了这种形式:
<强> 8.15.2。数组值输入
要将数组值写为文字常量,请将元素值括在花括号中并用逗号分隔。
我只使用'{...}'
版本,因为它更易于使用,并且更明确地说明数组元素的类型。
答案 1 :(得分:0)
不要做这个答案所暗示的,因为它是危险和脆弱的。这是我真正没有想到的事情之一,并且后悔在公开发表
您希望将数组文字的格式设置为'{"admin", "guest"}'
query_terms = ["admin", "guest"]
query = "{#{ query_terms.map {|term| %Q("#{ term }") }.join(",") }}"
where("? && roles", query)