如何使用Rails在一个查询中执行多个语句?

dee*_*pak 9 ruby postgresql activerecord ruby-on-rails ruby-on-rails-3

我正在使用带有ActiveRecord和PostgreSQL的Ruby on Rails.

如何执行多个SQL查询?

我需要它来运行自定义迁移脚本,例如:

Foo.connection.execute <<-SQL.split(';').map(&:strip).join
 delete from metadata where record_type = 'Foo';
 TRUNCATE table1 RESTART IDENTITY;
 TRUNCATE table2 RESTART IDENTITY;
 delete from schema_migrations where version > '20120806120823';
SQL
Run Code Online (Sandbox Code Playgroud)

我不接受用户的数据,所以我不担心sql注入.

CLIENT_MULTI_STATEMENTS也许像MySQL 这样的东西?

来自MySQL/PHP文档:

CLIENT_MULTI_STATEMENTS:告诉服务器客户端可以在一个字符串中发送多个语句(以";"分隔).如果未设置此标志,则禁用多语句执行.有关此标志的更多信息,请参阅此表后面的注释.

Ser*_*yuk 6

它应该与PostgreSQL开箱即用,用pg gem和rails 3.2检查:

class Multitest < ActiveRecord::Migration
  def up
    execute <<-SQL
      create table x(id serial primary key);
      create table y(id serial primary key, i integer);
    SQL
  end

  def down
  end
end
Run Code Online (Sandbox Code Playgroud)

另外,操纵schema_migrations直接看起来很奇怪.

  • 但是对MySQL不起作用.在Postgres上,ActiveRecord的执行成功多次,在MySQL上失败. (7认同)

fan*_*ing 5

对于 mysql

queries = File.read("/where/is/myqueries.sql")
# or
queries = <<-SQL
 TRUNCATE table1 RESTART IDENTITY;
 TRUNCATE table2 RESTART IDENTITY;
 delete from schema_migrations where version > '20120806120823';
SQL

queries.split(';').map(&:strip).each do |query| 
  execute(query)
end
Run Code Online (Sandbox Code Playgroud)

您可能也想看到这个问题: Invoking a large set of SQL from a Rails 4 application


Env*_*vek 5

是的,您需要CLIENT_MULTI_STATEMENTS

database.yml

development:
  adapter: mysql2
  database: project_development
  flags:
    - MULTI_STATEMENTS
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中:

connection.execute(multistatement_query)
# Hack for mysql2 adapter to be able query again after executing multistatement_query
connection.raw_connection.store_result while connection.raw_connection.next_result
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅/sf/answers/787278621/

  • 对于我这个 mysql 用户来说,在谷歌搜索一个通用的多语句问题后找到这个答案仍然很有用!:) (3认同)
  • 你没有阅读问题。这是针对 Postgres,而不是 MySQL。 (2认同)