Как вручную выполнять команды SQL в Ruby On Rails с помощью NuoDB

147

Я пытаюсь вручную выполнить команды SQL, чтобы получить доступ к процедурам в NuoDB.

Я использую Ruby on Rails и использую следующую команду:

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

«SQL-запрос» может быть любой SQL-командой.

Например, у меня есть таблица с названием «Feedback», и когда я выполняю команду:

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

Это вернет только «истинный» ответ, а не отправит мне все запрошенные данные.

Вывод на консоль Rails:

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

Я хотел бы использовать это для вызова хранимых процедур в NuoDB, но при вызове процедур это также вернет «истинный» ответ.

Могу ли я выполнить команды SQL и получить запрошенные данные вместо получения «истинного» ответа?

Патрик Ангодунг
источник

Ответы:

169

Рабочая команда, которую я использую для выполнения пользовательских операторов 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 вернет найденные записи, а если их нет, вернет nil.

Таким образом, я могу просто вызвать его в любом месте приложения rails, например:

records = execute_statement("select * from table")

«execute_statement» также может вызывать процедуры, функции NuoDB, а также представления базы данных.

Патрик Ангодунг
источник
3
лучше использовать exec_query, если вы используете PSQL, потому что это приведет к утечке памяти
23,
3
Я не могу найти разницу между кодом в вашем вопросе и в вашем ответе. Кажется, они оба используют ActiveRecord::Base.connection.execute. Не могли бы вы указать, что именно вы изменили для получения данных, а не просто true?
RocketR
128

Для меня я не мог заставить это вернуть хеш.

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

Но использование метода exec_query сработало.

results = ActiveRecord::Base.connection.exec_query(sql)
Тим Парк
источник
11
.exec_queryвозвращает ActiveRecord::Resultобъект , который очень удобно с легко доступным .columnsи .rowsатрибутами. .executeвозвращает массив хэшей, с которыми обычно труднее справиться и, вероятно, больше памяти. Никогда не пользовался exec_query, спасибо за подсказку.
Франсио Родригес
11
Просто чтобы добавить к последнему комментарию, вы обычно хотите использовать .entriesпри использовании .exec_queryдля получения результатов в виде массива хэшей.
8bithero
Это всегда дает мне ноль результатов, когда ActiveRecord 5 выполняет запрос DELETE?
Tom Rossi
29

Репост ответа с нашего форума, чтобы помочь другим решить аналогичную проблему:

@connection = ActiveRecord::Base.connection
result = @connection.exec_query('select tablename from system.tables')
result.each do |row|
puts row
end
MFredrickson-NuoDB
источник
24
res = ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query( "SELECT 1;" ) }

Приведенный выше код является примером для

  1. выполнение произвольного SQL в вашем соединении с базой данных
  2. после этого вернуть соединение обратно в пул соединений
Андреас Райо Книп
источник
3
Почему вы будете использовать пул соединений вместо самого соединения? Есть ли преимущество? У вас есть источник об этом?
bonafernando
4
@bonafernando, ваша база данных может начать выдавать ошибки «Слишком много соединений», если у вас есть код, который использует ActiveRecord::Base.connectionбез вызова ActiveRecord::Base.clear_active_connections!. См. Api.rubyonrails.org/v5.2/classes/ActiveRecord/…
eremite
Да, перед вашим ответом я изменился и заметил, что у меня никогда не было другой ошибки "Слишком много соединений". Благодарность!
бонафернандо