Як вручну виконувати команди 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:

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

Я хотів би використовувати це для виклику збережених процедур в NuoDB, але після виклику процедур це також поверне "справжню" відповідь.

Чи все-таки я можу виконувати команди SQL і отримувати запитувані дані, а не отримувати "справжню" відповідь?

Відповіді:


166

Робоча команда, яку я використовую для виконання спеціальних операторів SQL, це:

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

при цьому "foo" є оператором sql (тобто "SELECT * FROM table").

Ця команда поверне набір значень як хеш і поставить їх у змінну результатів.

Отже, на своїх рейках 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, оскільки це просочиться пам'яттю
23

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 виконує запит DELETE?
Том Россі

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 / ...
відлюдник

Так, перед вашою відповіддю я змінився і помітив, що ніколи не мав жодної іншої помилки "Занадто багато з'єднань". Дякую!
bonafernando
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.