ruby-on-rails Rails原始SQL示例

qco9c6ql  于 2023-03-31  发布在  Ruby
关注(0)|答案(6)|浏览(152)

我如何将这段代码转换成raw sql并在rails中使用?因为当我在heroku中部署这段代码时,会出现请求超时错误。我认为如果我使用raw sql,这会更快。

@payments = PaymentDetail.joins(:project).order('payment_details.created_at desc')
@payment_errors = PaymentError.joins(:project).order('payment_errors.created_at desc')

@all_payments = (@payments + @payment_errors)
pxyaymoc

pxyaymoc1#

您可以执行以下操作:

sql = "Select * from ... your sql query here"
records_array = ActiveRecord::Base.connection.execute(sql)

然后records_array将是一个数组中的SQL查询的结果,您可以对其进行迭代。

mwg9r5ms

mwg9r5ms2#

我知道这是旧的...但我今天遇到了同样的问题,并找到了解决方案:

Model.find_by_sql

如果要示例化结果:
x一个一个一个一个x一个一个二个x
如果你只想要一个哈希值:

Client.connection.select_all("SELECT first_name, created_at FROM clients
   WHERE id = '1'").to_hash
# => [
  {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"},
  {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"}
]

结果对象:
select_all返回一个result对象。你可以用它做一些神奇的事情。

result = Post.connection.select_all('SELECT id, title, body FROM posts')
# Get the column names of the result:
result.columns
# => ["id", "title", "body"]

# Get the record values of the result:
result.rows
# => [[1, "title_1", "body_1"],
      [2, "title_2", "body_2"],
      ...
     ]

# Get an array of hashes representing the result (column => value):
result.to_hash
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
      {"id" => 2, "title" => "title_2", "body" => "body_2"},
      ...
     ]

# ActiveRecord::Result also includes Enumerable.
result.each do |row|
  puts row['title'] + " " + row['body']
end

资料来源:

  1. ActiveRecord -通过SQL查找。
  2. Ruby on Rails - Active Record Result .
3gtaxfhh

3gtaxfhh3#

你可以使用ActiveRecord执行原始查询。我建议使用SQL块

query = <<-SQL 
  SELECT * 
  FROM payment_details
  INNER JOIN projects 
          ON projects.id = payment_details.project_id
  ORDER BY payment_details.created_at DESC
SQL

result = ActiveRecord::Base.connection.execute(query)
fhity93d

fhity93d4#

你可以直接使用SQL对两个表进行一个查询。我将提供一个经过清理的查询示例,希望避免人们直接将变量放入字符串本身(SQL注入危险),即使这个示例没有指定需要它:

@results = []
ActiveRecord::Base.connection.select_all(
  ActiveRecord::Base.send(:sanitize_sql_array, 
   ["... your SQL query goes here and ?, ?, ? are replaced...;", a, b, c])
).each do |record|
  # instead of an array of hashes, you could put in a custom object with attributes
  @results << {col_a_name: record["col_a_name"], col_b_name: record["col_b_name"], ...}
end
  • 编辑 *:如胡伊所说,一种简单的方法是ActiveRecord::Base.connection.execute("...")。另一种方法是ActiveRecord::Base.connection.exec_query('...').rows。并且您可以使用本地的预准备语句,例如如果使用postgres,则可以使用raw_connection,prepare和exec_prepared完成预准备语句,如https://stackoverflow.com/a/13806512/178651中所述

您还可以将原始SQL片段放入ActiveRecord关系查询中:http://guides.rubyonrails.org/active_record_querying.html和关联、作用域等。您可能可以使用ActiveRecord关系查询构造相同的SQL,并且可以使用ARel做一些很酷的事情,就像Ernie在http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/中提到的那样。
如果这将被大量使用,并且添加索引不会导致其他性能/资源问题,请考虑在DB中为payment_details.created_at和payment_errors.created_at添加索引。
如果需要同时显示许多记录而不是所有记录,请考虑使用分页:

如果需要分页,请考虑在数据库中创建一个名为payment_records的视图,该视图将payment_details和payment_errors表组合在一起,然后为视图创建一个模型(将是只读的)。一些数据库支持物化视图,这可能是提高性能的好主意。
还要考虑Rails服务器和DB服务器上的硬件或VM规格、配置、磁盘空间、网络速度/延迟/等、接近度等。如果没有,请考虑将DB放在Rails应用程序之外的不同服务器/VM上,等等。

jc3wubiy

jc3wubiy5#

我想使用ActiveRecord类的exec_query,因为它返回查询转换为对象的Map,所以当主题是Raw SQL时,迭代对象变得非常实用和高效。
示例:

values = ActiveRecord::Base.connection.exec_query("select * from clients")
p values

并返回以下完整查询:

[{"id": 1, "name": "user 1"}, {"id": 2, "name": "user 2"}, {"id": 3, "name": "user 3"}]

仅获取值列表

p values.rows

[[1, "user 1"], [2, "user 2"], [3, "user 3"]]

仅获取字段列

p values.columns

["id", "name"]
omqzjyyz

omqzjyyz6#

您还可以将原始SQL与ActiveRecord条件混合使用,例如,如果您希望在条件中调用函数:

my_instances = MyModel.where.not(attribute_a: nil)
  .where('crc32(attribute_b) = ?', slot)
  .select(:id)

相关问题