Rails 3 menjalankan kueri sql khusus tanpa model

105

Saya perlu menulis skrip ruby ​​mandiri yang seharusnya menangani database. Saya menggunakan kode yang diberikan di bawah ini di rel 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

tetapi mendapatkan kesalahan: -

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

apa yang saya lewatkan di sini?

LARUTAN

Setelah mendapatkan solusi dari denis-bu saya menggunakannya dengan cara berikut dan itu berhasil juga.

@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
neeraj
sumber

Jawaban:

168

Mungkin coba ini:

ActiveRecord::Base.establish_connection(...)
ActiveRecord::Base.connection.execute(...)
denis-bu
sumber
14
FWIW, Menggunakan parameter kosong bukanlah ruby ​​idiomatis. Jadi lakukan connection.executedaripadaconnection().execute
radixhound
Bekerja pada Rails 4 juga.
Leigh McCulloch
github.com/igorkasyanchuk/execute_sql lebih sedikit kode yang diperlukan plus Anda dapat melakukannya di konsol rel langsung
Igor Kasyanchuk
100
connection = ActiveRecord::Base.connection
connection.execute("SQL query") 
Sachin R
sumber
8
Dalam kasus ini, connection = ActiveRecord :: Base.connection; connection.execute ("SQL query") akan berfungsi. Kurangi mengetik!
Watusimoto
16
Atau hanyaActiveRecord::Base.connection.execute("SQL query")
Kasper Grubbe
3
Koneksi ini mungkin harus dikembalikan ke kumpulan koneksi setelahnya untuk menghindari masalah threading: ActiveRecord::Base.connection_pool.checkin(connection) apidock.com/rails/ActiveRecord/ConnectionAdapters/…
lee
35

Saya akan merekomendasikan menggunakan ActiveRecord::Base.connection.exec_queryalih-alih ActiveRecord::Base.connection.executeyang mengembalikan ActiveRecord::Result(tersedia di rel 3.1+) yang sedikit lebih mudah untuk dikerjakan.

Kemudian Anda dapat mengaksesnya di berbagai hasilnya dalam berbagai cara seperti .rows, .each, atau.to_hash

Dari dokumen :

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

catatan: menyalin jawaban saya dari sini

hajpoj
sumber
1
Seperti yang dinyatakan, exec_query mengembalikan hasil sebenarnya - apa yang saya inginkan, sementara mengeksekusi hanya mengembalikan informasi status.
Paul Chernoch
24

Anda juga bisa menggunakan 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"}>, ...]
montrealmike
sumber
skrip saya berada di luar aplikasi rel jadi saya rasa find_by_sql tidak akan berfungsi.
neeraj
4
Anda benar, saya membaca pertanyaan Anda terlalu cepat. Jawaban ini mungkin membantu orang lain yang datang ke halaman ini berdasarkan judul pertanyaan Anda.
montrealmike
bagaimana cara mendapatkan bukan sebuah array tapi relasi?
Малъ Скрылевъ
4

Bagaimana dengan ini :

@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

Anda perlu menginstal permata TinyTds, karena Anda tidak menentukannya dalam pertanyaan Anda, saya tidak menggunakan Rekaman Aktif

semut
sumber
1
Tentu, TinyTds adalah permata lainnya .. Ini bukan ActiveRecord. Untuk menggunakannya, Anda harus menginstalnya secara terpisah.
denis-bu
1
Saya tidak ingin menggunakan GEM tambahan selama mysql2 dan catatan aktif tersedia
neeraj
Bagus, Anda harus menyebutkannya dalam pertanyaan Anda (tag / judul)
semut
2
TinyTDS bekerja dengan MSSQL dan Sybase, tidak bekerja dengan MySQL. ant: Anda harus menyebutkannya dalam jawaban Anda, dan tidak berasumsi bahwa OP menggunakan DBMS niche yang sama seperti Anda.
cliffordheath