【问题标题】:SQL query (Postgres) works normally, but not through ActiveRecordSQL 查询(Postgres)正常工作,但不能通过 ActiveRecord
【发布时间】:2012-04-10 13:01:44
【问题描述】:

我在 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}'

这让它呕吐,但我就是不知道为什么......任何建议将不胜感激!

【问题讨论】:

  • 查看 development.log 文件;您将看到变体产生的实际 SQL。如果不清楚它们与那有何不同,请发布差异(真实的,没有“等等,等等”:-),有人可能会帮助“解释差异”。

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


【解决方案1】:

您需要将 \ 加倍以将 \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"]] 

【讨论】:

    猜你喜欢
    • 2015-07-18
    • 1970-01-01
    • 2013-01-31
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多