คุณจะรันคำสั่ง SQL ด้วยตนเองใน Ruby On Rails โดยใช้ NuoDB อย่างไร


142

ฉันพยายามรันคำสั่ง SQL ด้วยตนเองเพื่อให้ฉันสามารถเข้าถึงโพรซีเดอร์ใน NuoDB

ฉันใช้ Ruby on Rails และฉันใช้คำสั่งต่อไปนี้:

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

"แบบสอบถาม SQL" อาจเป็นคำสั่ง SQL ใด ๆ

ตัวอย่างเช่นฉันมีตารางชื่อ "คำติชม" และเมื่อฉันรันคำสั่ง:

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

สิ่งนี้จะส่งกลับการตอบสนอง "จริง" แทนที่จะส่งข้อมูลทั้งหมดที่ขอมาให้ฉัน

นี่คือผลลัพธ์บน Rails Console คือ:

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

ฉันต้องการใช้วิธีนี้เพื่อเรียกโพรซีเดอร์ที่เก็บไว้ใน NuoDB แต่เมื่อเรียกโพรซีเดอร์นี้จะส่งคืนการตอบกลับที่ "จริง"

มีอยู่แล้วฉันสามารถดำเนินการคำสั่ง SQL และรับข้อมูลที่ร้องขอแทนที่จะได้รับการตอบสนอง "จริง"?

คำตอบ:


166

คำสั่งการทำงานที่ฉันใช้เพื่อรันคำสั่ง SQL แบบกำหนดเองคือ:

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

ด้วย "foo" เป็นคำสั่ง sql (เช่น "SELECT * FROM table")

คำสั่งนี้จะส่งคืนชุดของค่าเป็นแฮชและวางลงในตัวแปรผลลัพธ์

ดังนั้นบน Rails ของฉัน application_controller.rb ฉันได้เพิ่มสิ่งนี้:

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

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

การใช้ execute_statement จะส่งคืนระเบียนที่พบและหากไม่มีก็จะส่งคืนศูนย์

ด้วยวิธีนี้ฉันสามารถเรียกมันได้ทุกที่บนแอปพลิเคชันทางรถไฟเช่น:

records = execute_statement("select * from table")

"execute_statement" ยังสามารถเรียกใช้โพรซีเดอร์ฟังก์ชันและมุมมองฐานข้อมูลของ NuoDB ได้อีกด้วย


3
มันจะดีกว่าถ้าใช้ exec_query ถ้าคุณใช้ PSQL เพราะมันจะทำให้หน่วยความจำรั่วไหล
23inhouse

3
ฉันไม่พบความแตกต่างระหว่างรหัสในคำถามของคุณและในคำตอบของคุณ ActiveRecord::Base.connection.executeพวกเขาทั้งสองดูเหมือนจะใช้ คุณช่วยชี้ให้เห็นว่าคุณเปลี่ยนแปลงอะไรเพื่อให้ได้ข้อมูลแทนที่จะเป็นแค่trueอะไร?
RocketR

120

สำหรับฉันฉันไม่สามารถรับมันคืนแฮชได้

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

แต่ใช้วิธีการทำงานของ exec_query

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

10
.exec_queryส่งคืนActiveRecord::Resultวัตถุซึ่งมีประโยชน์มากด้วยการเข้าถึงได้ง่าย.columnsและ.rowsคุณลักษณะ .executeส่งคืนอาร์เรย์ของแฮชซึ่งมักจะลำบากกว่าในการจัดการและอาจหนักกว่าในหน่วยความจำ ฉันไม่เคยใช้exec_queryขอบคุณสำหรับเคล็ดลับ
Francio Rodrigues

9
เพียงเพื่อเพิ่มความคิดเห็นล่าสุดคุณมักจะต้องการใช้.entriesเมื่อใช้.exec_queryเพื่อให้ได้ผลลัพธ์เป็นอาร์เรย์ของแฮช
8bithero

สิ่งนี้ทำให้ฉันไม่มีผลลัพธ์เสมอเมื่อใช้ ActiveRecord 5 ในการลบคิวรี
Tom Rossi

27

โพสต์คำตอบอีกครั้งจากฟอรัมของเราเพื่อช่วยเหลือผู้อื่นในปัญหาที่คล้ายกัน:

@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;" ) }

โค้ดด้านบนเป็นตัวอย่างสำหรับ

  1. รัน SQL โดยพลการบนการเชื่อมต่อฐานข้อมูลของคุณ
  2. คืนการเชื่อมต่อกลับไปที่พูลการเชื่อมต่อหลังจากนั้น

2
ทำไมคุณจะใช้กลุ่มการเชื่อมต่อแทนการเชื่อมต่อตัวเอง มีข้อได้เปรียบอะไรบ้าง? คุณจะมีแหล่งที่มาเกี่ยวกับเรื่องนี้หรือไม่?
bonafernando

3
@bonafernando ฐานข้อมูลของคุณอาจเริ่มขว้าง "การเชื่อมต่อมากเกินไป" ข้อผิดพลาดถ้าคุณมีรหัสที่ใช้โดยไม่ต้องโทรActiveRecord::Base.connection ActiveRecord::Base.clear_active_connections!ดูapi.rubyonrails.org/v5.2/classes/ActiveRecord/ …
eremite

ใช่ก่อนคำตอบของคุณฉันเปลี่ยนไปและสังเกตว่าฉันไม่เคยมีข้อผิดพลาด "การเชื่อมต่อมากเกินไป" อื่น ๆ ขอบคุณ!
bonafernando
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.