¿Cómo se ejecutan manualmente los comandos SQL en Ruby On Rails usando NuoDB?

142

Estoy tratando de ejecutar manualmente comandos SQL para poder acceder a los procedimientos en NuoDB.

Estoy usando Ruby on Rails y estoy usando el siguiente comando:

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

La "consulta SQL" podría ser cualquier comando SQL.

Por ejemplo, tengo una tabla llamada "Comentarios" y cuando ejecuto el comando:

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

Esto solo devolvería una respuesta "verdadera" en lugar de enviarme todos los datos solicitados.

Esta es la salida en la consola de Rails es:

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

Me gustaría usar esto para llamar a procedimientos almacenados en NuoDB pero al llamar a los procedimientos, esto también devolvería una respuesta "verdadera".

¿Hay alguna forma de ejecutar comandos SQL y obtener los datos solicitados en lugar de obtener una respuesta "verdadera"?

Patrick Angodung
fuente

Respuestas:

166

El comando de trabajo que estoy usando para ejecutar sentencias SQL personalizadas es:

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

con "foo" como la instrucción sql (es decir, "SELECT * FROM table").

Este comando devolverá un conjunto de valores como un hash y los colocará en la variable de resultados.

Entonces, en mis rieles application_controller.rb agregué esto:

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

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

El uso de execute_statement devolverá los registros encontrados y, si no hay ninguno, devolverá nil.

De esta manera, puedo llamarlo en cualquier lugar de la aplicación de rieles como, por ejemplo:

records = execute_statement("select * from table")

"execute_statement" también puede llamar a procedimientos, funciones y también vistas de base de datos de NuoDB.

Patrick Angodung
fuente
3
es mejor usar exec_query si está en PSQL porque va a perder memoria
23inhouse
3
No puedo encontrar la diferencia entre el código en su pregunta y en su respuesta. Ambos parecen usar ActiveRecord::Base.connection.execute. ¿Podría indicar qué cambió exactamente para obtener los datos en lugar de solo true?
RocketR
119

Para mí, no pude obtener esto para devolver un hash.

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

Pero usar el método exec_query funcionó.

results = ActiveRecord::Base.connection.exec_query(sql)
Tim Park
fuente
10
.exec_querydevuelve un ActiveRecord::Resultobjeto que es muy útil con fácil acceso .columnsy .rowsatributos. .executedevuelve una serie de hashes que generalmente es más problemático de manejar y probablemente más pesado en la memoria. Nunca lo había usado exec_query, gracias por el dato.
Francio Rodrigues
9
Solo para agregar al último comentario, generalmente querrá usarlo .entriescuando lo use .exec_querypara obtener los resultados como una matriz de hashes.
8bithero
¿Esto siempre me da nulo para los resultados con ActiveRecord 5 ejecutando una consulta DELETE?
Tom Rossi
27

Reposicionando la respuesta de nuestro foro para ayudar a otros con un problema similar:

@connection = ActiveRecord::Base.connection
result = @connection.exec_query('select tablename from system.tables')
result.each do |row|
puts row
end
MFredrickson-NuoDB
fuente
22
res = ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query( "SELECT 1;" ) }

El código anterior es un ejemplo para

  1. ejecutar SQL arbitrario en su conexión de base de datos
  2. devolver la conexión al grupo de conexiones después
Andreas Rayo Kniep
fuente
2
¿Por qué usará el grupo de conexiones en lugar de la conexión en sí? ¿Hay alguna ventaja? ¿Tendría una fuente al respecto?
bonafernando
3
@bonafernando, su base de datos podría comenzar a arrojar errores de "Demasiadas conexiones" si tiene un código que usa ActiveRecord::Base.connectionsin llamar ActiveRecord::Base.clear_active_connections!. Ver api.rubyonrails.org/v5.2/classes/ActiveRecord/...
eremite
Sí, antes de su respuesta, he cambiado y noté que nunca he tenido ningún otro error de "Demasiadas conexiones". ¡Gracias!
bonafernando