Sql Rails中的原始数据库查询

Sql Rails中的原始数据库查询,sql,ruby-on-rails,postgresql,ruby-on-rails-4,pg,Sql,Ruby On Rails,Postgresql,Ruby On Rails 4,Pg,我试图在rails中运行以下原始查询,但结果却失败了: query = 'SELECT * FROM users WHERE id IN ($1);' results = ActiveRecord::Base.connection.exec_query(query, "My query", [ [1,2] ]); 我做错了什么 我遇到的错误是这样开始的: Could not log "sql.active_record" event. NoMethodError: undefined me

我试图在rails中运行以下原始查询,但结果却失败了:

query   = 'SELECT * FROM users WHERE id IN ($1);'
results = ActiveRecord::Base.connection.exec_query(query, "My query", [ [1,2] ]);
我做错了什么

我遇到的错误是这样开始的:

Could not log "sql.active_record" event. NoMethodError: undefined method `binary?' for 1:Fixnum
显然,我不知何故误用了[1,2]bind参数,但我自己找不到合适的例子

另外,这是一个最小的失败例子,它源自一个更高级的查询,无法转换为ActiveRecord调用链。换句话说,在构建查询时,我不能依赖Arel


p.p.S.我使用的是rails 4.0.1和postgresql 9.3

我很确定您的命名错误来自日志记录。如果我们看一下,我们会看到:

def exec_query(sql, name = 'SQL', binds = [])
  log(sql, name, binds) do
    # call exec_no_cache(sql, binds) or exec_cache(sql, binds)...
def exec_cache(sql, binds)
  #..
  @connection.send_query_prepared(stmt_key, binds.map { |col, val|
    type_cast(val, col)
  })
如果我们看一下,我们会看到:

def exec_query(sql, name = 'SQL', binds = [])
  log(sql, name, binds) do
    # call exec_no_cache(sql, binds) or exec_cache(sql, binds)...
def exec_cache(sql, binds)
  #..
  @connection.send_query_prepared(stmt_key, binds.map { |col, val|
    type_cast(val, col)
  })
因此绑定应该是列/值对。PostgreSQL驱动程序希望col是一个列对象,这样它就可以询问col的名称以及它应该如何格式化val,exec_查询中的日志调用使用这些信息在Rails日志中生成一些漂亮的、人类可读的内容。一些实验表明,你可以使用nil作为col,一切都很愉快

这意味着我们已经进入了这一阶段:

exec_query(
  'SELECT * FROM users WHERE id IN ($1)',
  'my query',
  [ [nil, [1,2]] ]
)
底层驱动程序可能不知道如何处理[1,2]数组,我只有带有PostgreSQL扩展的Rails3可供测试,它不喜欢[1,2]。如果Rails4也不喜欢该数组,则可以逐个传递参数:

exec_query(
  'SELECT * FROM users WHERE id IN ($1, $2)',
  'my query',
  [ [nil,1], [nil,2] ]
)

我最近遇到了类似的问题。事实证明,在where-in中,ActiveRecord需要的是字符串,而不是数组。因此,您可以尝试传入一个逗号分隔的ID字符串,这样就可以了。

我不确定postgresql,因为我通常查询MySQL。但无论如何,语法应该是相同的。Try:query='SELECT*来自id所在的用户;'results=ActiveRecord::Base.connection.exec_queryqueryquery,[1,2]我也遇到了这个问题,但通过这样做解决了这个问题:sql=SELECT*FROM table_a,其中identifier IN WHERE_equals=[id_1,id_2]ActiveRecord::Base.connection.exec_queryActiveRecord::Base.send:sanitize_sql_array,[sql,WHERE_equals]语法一开始对我不起作用。我切换到使用备用“%s”语法,然后最终使用哈希语法。e、 g.清理_sql_数组[name=:name和group_id=:group_id,name:foo'bar,group_id:4]=>name='foobar'和group_id=4清理_sql_数组[name='%s'和group_id='%s',foo'bar,4]=>name='foobar'和group_id='4'来自