Hstore ActiveRecord使用通配符查询键和值

时间:2014-01-26 17:46:46

标签: ruby-on-rails postgresql activerecord rails-activerecord hstore

我想在我的rails app中使用这样的查询:

Series.where("dimensions @> 'a=>1, b=>2'::hstore")

除了我需要使用通配符(或命名参数)以便不引入SQL注入错误:

Series.where("dimensions @> '?=>?, ?=>?'::hstore", 'a', '1', 'b', '2')

然而后者不起作用,因为hstore不希望用单引号引用键/值。这是错误:

PG::SyntaxError: ERROR:  syntax error at or near "a"
LINE 1: ... "series".* FROM "series"  WHERE (dimensions @> ''a'=>'1', '...
                                                             ^
: SELECT "series".* FROM "series"  WHERE (dimensions @> ''a'=>'1', 'b'=>'2''::hstore)

在hstore中使用通配符的正确方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

还有其他ways to construct an hstore而不是使用text-to-hstore强制转换:

  • hstore(text[]):从数组构造一个hstore,它可以是键/值数组,也可以是二维数组。
  • hstore(text[], text[]):从单独的键和值数组构建一个hstore。
  • hstore(text, text):制作单项hstore。

所以你可以做这些事情:

hstore('k', 'v')                             -- "k"=>"v"
hstore(array['k1', 'k2'], array['v1', 'v2']) -- "k1"=>"v1", "k2"=>"v2"
hstore(array['k1', 'v1', 'k2', 'v2'])        -- "k1"=>"v1", "k2"=>"v2"
hstore(array[['k1', 'v1'], ['k2', 'v2']])    -- "k1"=>"v1", "k2"=>"v2"

也许你会更成功:

Series.where('dimensions @> hstore(array[:k1, :v1, :k2, :v2])',
  :k1 => 'a', :v1 => '1',
  :k2 => 'b', :v2 => '2'
)

该版本只有一个级别的引号,因此AR不应该弄乱。我也一路上切换到命名占位符,超过几个匿名占位符让人感到困惑。