用于删除反斜杠的Postgres命令在控制台中工作,但不能在ActiveRecord :: Base.connection.execute中工作

时间:2018-03-14 21:16:13

标签: ruby-on-rails postgresql activerecord pg

此Postgres命令在从psql命令行运行时删除所有反斜杠:

UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g');

此Rails命令不起作用(它运行时没有错误,但不会删除反斜杠):

ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g'))

看起来Rails更改了查询并运行它(我检查了在控制台中运行查询的输出):

UPDATE table SET column = REGEXP_REPLACE(column, 'B', '', 'g')

Postgres命令在从psql命令行运行时也成功删除了反斜杠:

UPDATE table SET column = REGEXP_REPLACE(column, '\\', '', 'g')

使用Rails运行时,同样的Postgres命令出错了:

ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\\', '', 'g')")

这是错误:

  

PG :: InvalidRegularExpression:错误:正则表达式无效:   无效的转义\序列

这是我Gemfile中设置的Postgres版本:

gem 'pg', '>= 0.18', '< 2.0'

你能解释为什么我收到这个错误以及如何编写Rails代码来删除列中的所有反斜杠?这将在大型数据集上运行,我需要快速解决方案。

1 个答案:

答案 0 :(得分:1)

您想要做的事情很复杂,因为有多种事情需要以自己的方式解释\

  1. \表示Ruby中双引号字符串中的内容。所以"\B"只是在Ruby中编写"B"的一种误导和复杂的方式。您需要说"\\B"以获取包含两个字符\B的字符串。

  2. \表示PostgreSQL正则表达式中的内容。因此在PostgreSQL的正则表达式中存在\B,这样你在查看另一种语言中的\之类的东西时就不必计算\\\\,你只需要稍微不那么丑陋的东西比如\\B

  3. 要解决您的问题,您可以正确地逃避逃脱:

    ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\\B', '', 'g')")
    

    当数据库看到时,它会看到:

    UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g')
    

    因为\\表示在双引号Ruby字符串中“只给我一个\”。

    我可能会进一步简化并使用SQL replace function

      

    replace(string text, from text, to text)
      将子字符串字符串中的所有匹配项替换为,将子字符串替换为

    与Ruby中的%q{...}字符串结合使用:

    ActiveRecord::Base.connection.execute(%q{
      update table
      set column = replace(column, '\', '')
    })
    

    %q{...}摆脱了一个转义问题,因为它在Ruby中就像一个单引号字符串,因此\并不意味着什么特别的。在SQL中使用replace可以解决另一个转义问题,因为它只适用于普通的旧字符串(而不是字符串表示的正则表达式),因此\再次没有任何意义。