Làm thế nào để bạn thực hiện thủ công các lệnh SQL trong Ruby On Rails bằng NuoDB


142

Tôi đang cố gắng thực hiện các lệnh SQL theo cách thủ công để tôi có thể truy cập các quy trình trong NuoDB.

Tôi đang sử dụng Ruby on Rails và tôi đang sử dụng lệnh sau:

ActiveRecord::Base.connection.execute("SQL query")

"Truy vấn SQL" có thể là bất kỳ lệnh SQL nào.

Ví dụ như tôi có một bảng gọi là "Phản hồi" và khi tôi thực hiện lệnh:

ActiveRecord::Base.connection.execute("SELECT `feedbacks`.* FROM `feedbacks`")

Điều này sẽ chỉ trả về phản hồi "đúng" thay vì gửi cho tôi tất cả dữ liệu được yêu cầu.

Đây là đầu ra trên Bảng điều khiển Rails là:

SQL (0.4ms)  SELECT `feedbacks`.* FROM `feedbacks`
 => true

Tôi muốn sử dụng điều này để gọi các thủ tục được lưu trữ trong NuoDB nhưng khi gọi các thủ tục, điều này cũng sẽ trả về phản hồi "đúng".

Có cách nào tôi có thể thực thi các lệnh SQL và nhận dữ liệu được yêu cầu thay vì nhận được phản hồi "đúng" không?

Câu trả lời:


166

Lệnh làm việc tôi đang sử dụng để thực thi các câu lệnh SQL tùy chỉnh là:

results = ActiveRecord::Base.connection.execute("foo")

với "foo" là câu lệnh sql (tức là "CHỌN * TỪ bảng").

Lệnh này sẽ trả về một tập hợp các giá trị dưới dạng băm và đưa chúng vào biến kết quả.

Vì vậy, trên rails application_controll.rb tôi đã thêm cái này:

def execute_statement(sql)
  results = ActiveRecord::Base.connection.execute(sql)

  if results.present?
    return results
  else
    return nil
  end
end

Sử dụng exec_statement sẽ trả về các bản ghi được tìm thấy và nếu không có, nó sẽ trả về con số không.

Bằng cách này, tôi có thể gọi nó ở bất cứ đâu trên ứng dụng rails như ví dụ:

records = execute_statement("select * from table")

"exec_statement" cũng có thể gọi các thủ tục, hàm và NuoDB cơ sở dữ liệu.


3
tốt hơn là sử dụng exec_query nếu bạn đang sử dụng PSQL vì nó sẽ bị rò rỉ bộ nhớ
23inhouse

3
Tôi không thể tìm thấy sự khác biệt giữa mã trong câu hỏi của bạn và trong câu trả lời của bạn. Cả hai dường như sử dụng ActiveRecord::Base.connection.execute. Bạn có thể vui lòng chỉ ra chính xác những gì bạn đã thay đổi để có được dữ liệu thay vì chỉ true?
RocketR

119

Đối với tôi, tôi không thể có được điều này để trả lại một hàm băm.

results = ActiveRecord::Base.connection.execute(sql)

Nhưng sử dụng phương thức exec_query đã làm việc.

results = ActiveRecord::Base.connection.exec_query(sql)

10
.exec_querytrả về một ActiveRecord::Resultđối tượng rất tiện dụng với các thuộc tính .columns.rowsthuộc tính dễ truy cập . .executetrả về một mảng băm thường gây rắc rối hơn và có thể nặng hơn về bộ nhớ. Tôi chưa bao giờ sử dụng exec_query, cảm ơn vì tiền boa.
Francio Coleues

9
Chỉ cần thêm vào nhận xét cuối cùng, bạn thường muốn sử dụng .entrieskhi sử dụng .exec_queryđể nhận kết quả dưới dạng một mảng băm.
8bithero

Điều này luôn mang lại cho tôi con số không cho kết quả với ActiveRecord 5 đang chạy truy vấn XÓA?
Tom Rossi

27

Đăng lại câu trả lời từ diễn đàn của chúng tôi để giúp những người khác có vấn đề tương tự:

@connection = ActiveRecord::Base.connection
result = @connection.exec_query('select tablename from system.tables')
result.each do |row|
puts row
end

22
res = ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query( "SELECT 1;" ) }

Đoạn mã trên là một ví dụ cho

  1. thực thi SQL tùy ý trên kết nối cơ sở dữ liệu của bạn
  2. sau đó trả kết nối trở lại nhóm kết nối

2
Tại sao bạn sẽ sử dụng nhóm kết nối thay vì chính kết nối? Có lợi thế gì không? Bạn sẽ có một nguồn về nó?
bonafernando

3
@bonafernando, cơ sở dữ liệu của bạn có thể bắt đầu ném "Quá nhiều kết nối" lỗi nếu bạn có mã mà sử dụng ActiveRecord::Base.connectionmà không gọi ActiveRecord::Base.clear_active_connections!. Xem api.rubyonrails.org/v5.2/groupes/ActiveRecord/iêu
eremite

Vâng, trước câu trả lời của bạn, tôi đã thay đổi và nhận thấy tôi chưa bao giờ gặp phải lỗi "Quá nhiều kết nối" khác. Cảm ơn!
bonafernando
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.