SQL查询(Postgres)可以正常工作,但不能通过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)

有趣的是,如果我去掉最后一个内部连接行,特别是regex匹配,它会返回一些东西。所以有一些东西:

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

这让它吐了,但我不明白为什么。。。如有任何建议,我们将不胜感激!

您需要将加倍才能将w降到正则表达式引擎,然后必须将每个值加倍才能通过Ruby的字符串文字处理。您应该使用E''来避免出现警告。此外,您不需要额外的SELECT,您可以直接比较regexp_matches返回值。所以,像这样的东西应该起作用:

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

没有必要在PostgreSQL正则表达式中转义斜杠,所以我也去掉了它。当他们都想使用相同的转义符时,将一种语言(regex)嵌入一种语言中(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"]] 

相关内容

最新更新