【问题标题】:Rails 3 execute custom sql query without a modelRails 3 在没有模型的情况下执行自定义 sql 查询
【发布时间】:2013-03-14 11:42:00
【问题描述】:

我需要编写一个独立的 ruby​​ 脚本来处理数据库。我在rails 3中使用了下面给出的代码

@connection = ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "localhost",
:database => "siteconfig_development",
:username => "root",
:password => "root123"
)

results = @connection.execute("select * from users")
results.each do |row|
puts row[0]
end

但出现错误:-

`<main>': undefined method `execute' for #<ActiveRecord::ConnectionAdapters::ConnectionPool:0x00000002867548> (NoMethodError)

我在这里缺少什么?

解决方案

从 denis-bu 获得解决方案后,我按照以下方式使用它,并且效果也很好。

@connection = ActiveRecord::Base.establish_connection(
            :adapter => "mysql2",
            :host => "localhost",
            :database => "siteconfig_development",
            :username => "root",
            :password => "root123"
)

sql = "SELECT * from users"
@result = @connection.connection.execute(sql);
@result.each(:as => :hash) do |row| 
   puts row["email"] 
end

【问题讨论】:

    标签: sql ruby-on-rails


    【解决方案1】:

    我建议使用ActiveRecord::Base.connection.exec_query 而不是ActiveRecord::Base.connection.execute,它返回一个更容易使用的ActiveRecord::Result(在rails 3.1+ 中可用)。

    然后您可以通过各种方式访问​​它,例如.rows.each.to_hash

    来自docs

    result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
    result # => #<ActiveRecord::Result:0xdeadbeef>
    
    
    # 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
    

    注意:从here复制我的答案

    【讨论】:

    • 如前所述,exec_query 返回实际结果——我想要的,而 execute 只返回状态信息。
    【解决方案2】:

    你也可以使用find_by_sql

    # A simple SQL query spanning multiple tables
    Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
    > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
    

    【讨论】:

    • 我的脚本在 Rails 应用程序之外,所以我认为 find_by_sql 不起作用。
    • 你是对的,我读你的问题太快了。根据您的问题标题,此答案可能会对访问此页面的其他人有所帮助。
    • 如何获取不是数组而是关系?
    【解决方案3】:

    不妨试试这个:

    ActiveRecord::Base.establish_connection(...)
    ActiveRecord::Base.connection.execute(...)
    

    【讨论】:

    • FWIW,使用空参数不是惯用的 ruby​​。 connection.execute 而不是 connection().execute 也是如此
    • 也适用于 Rails 4。
    • github.com/igorkasyanchuk/execute_sql 需要更少的代码,而且您可以直接在 Rails 控制台中完成
    【解决方案4】:
    connection = ActiveRecord::Base.connection
    connection.execute("SQL query") 
    

    【讨论】:

    • 在这种情况下,connection = ActiveRecord::Base.connection; connection.execute("SQL query") 会起作用。少打字!
    • 或者只是ActiveRecord::Base.connection.execute("SQL query")
    • 这个连接可能必须在之后返回到连接池以避免线程问题:ActiveRecord::Base.connection_pool.checkin(connection)apidock.com/rails/ActiveRecord/ConnectionAdapters/…
    【解决方案5】:

    这个怎么样:

    @client = TinyTds::Client.new(
          :adapter => 'mysql2',
          :host => 'host',
          :database => 'siteconfig_development',
          :username => 'username',
          :password => 'password'
    
    sql = "SELECT * FROM users"
    
    result = @client.execute(sql)
    
    results.each do |row|
    puts row[0]
    end
    

    您需要安装 TinyTds gem,因为您没有在问题中指定它我没有使用 Active Record

    【讨论】:

    • 当然,TinyTds 完全是另一种宝石。它不是 ActiveRecord。要使用它,您应该单独安装它。
    • 只要 mysql2 和 active-record 可用,我不想使用任何额外的 GEM
    • 好,你应该在你的问题中提到这一点(标签/标题)
    • TinyTDS 适用于 MSSQL 和 Sybase,但不适用于 MySQL。 ant:应该在你的回答中提到这一点,而不是假设 OP 使用的是与你相同的利基 DBMS。
    猜你喜欢
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多