SQL查询(Postgres)正常工作,但不能通过ActiveRecord

时间:2012-03-27 01:09:33

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

我在Postgres中有一个SQL查询,它可以在SQL控制台/工具中正常工作,但不能通过Rails的ActiveRecord(ActiveRecord :: Base.connection.execute / select_all)工作。我尝试了一些像转义引号的东西,调用ActiveRecord :: Base.quote / sanitize无济于事 - ActiveRecord返回一个空集,我已经验证了这个查询返回了一个元组。

SELECT
      ... blah blah
      FROM
        ... joins joins joins
        inner join core.pat_assignments assignment on assignment.correspondent_alias_id = out_alias.id
        inner join core.pats patent on patent.id = assignment.pat_id and (select regexp_matches(patent.us_class_current, '(\w+)\/')) = '{D02}'
      where
        in_alias.id in (1987, 5004)

有趣的是,如果我取出最后一条内部连接线,特别是正则表达式匹配,它会返回一些内容。所以有一些东西:

(select regexp_matches(patent.us_class_current, '(\w+)\/')) = '{D02}'

这是让它呕吐,但我无法弄清楚为什么......任何建议都会非常感激!

1 个答案:

答案 0 :(得分:3)

您需要将\加倍才能将\w缩减到正则表达式引擎,然后您必须将每个加倍,以使它们超过Ruby的字符串文字处理。您应该使用E''来避免警告。此外,您不需要额外的SELECT,您可以直接比较regexp_matches返回值。所以,这样的事情应该有效:

inner join ... and regexp_matches(patent.us_class_current, E'(\\\\w+)/') = array['D02']

没有必要在PostgreSQL正则表达式中删除斜杠,所以我也把它拿掉了。在一种语言(PostgreSQL的SQL)中嵌入一种语言(正则表达式)在另一种语言(Ruby)中,当他们都想使用相同的转义字符时,往往会有点混乱。

例如,在psql这些事情发生了:

psql=> select regexp_matches('D03/pancakes', E'(\w+)/');
 regexp_matches 
----------------
(0 rows)

psql=> select regexp_matches('D03/pancakes', E'(\\w+)/');
 regexp_matches 
----------------
 {D03}
(1 row)

psql=> select regexp_matches('D03/pancakes', E'(\\w+)/') = array['D03'];
 ?column? 
----------
 t
(1 row)

然后从Rails控制台:

> ActiveRecord::Base.connection.select_rows(%q{select regexp_matches('D03/pancakes', E'(\w+)/')})
   (0.5ms)  select regexp_matches('D03/pancakes', E'(\w+)/')
 => [] 
> ActiveRecord::Base.connection.select_rows(%q{select regexp_matches('D03/pancakes', E'(\\w+)/')})
   (1.9ms)  select regexp_matches('D03/pancakes', E'(\w+)/')
 => [] 
> ActiveRecord::Base.connection.select_rows(%q{select regexp_matches('D03/pancakes', E'(\\\\w+)/')})
   (0.4ms)  select regexp_matches('D03/pancakes', E'(\\w+)/')
 => [["{D03}"]] 
> ActiveRecord::Base.connection.select_rows(%q{select regexp_matches('D03/pancakes', E'(\\\\w+)/') = array['D03']})
   (1.4ms)  select regexp_matches('D03/pancakes', E'(\\w+)/') = array['D03']
 => [["t"]]