Como você executa manualmente comandos SQL no Ruby On Rails usando o NuoDB


142

Estou tentando executar manualmente comandos SQL para acessar procedimentos no NuoDB.

Estou usando Ruby on Rails e estou usando o seguinte comando:

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

A "consulta SQL" pode ser qualquer comando SQL.

Como por exemplo, eu tenho uma tabela chamada "Feedback" e quando executo o comando:

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

Isso retornaria apenas uma resposta "verdadeira" em vez de me enviar todos os dados solicitados.

Esta é a saída no console do Rails:

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

Gostaria de usar isso para chamar procedimentos armazenados no NuoDB, mas, ao chamar os procedimentos, isso também retornaria uma resposta "verdadeira".

Existe alguma maneira de executar comandos SQL e obter os dados solicitados em vez de obter uma resposta "verdadeira"?

Respostas:


166

O comando de trabalho que estou usando para executar instruções SQL personalizadas é:

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

com "foo" sendo a instrução sql (ou seja, "SELECT * FROM tabela").

Este comando retornará um conjunto de valores como um hash e os colocará na variável results.

Então, no meu rails application_controller.rb eu adicionei isso:

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

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

O uso de execute_statement retornará os registros encontrados e, se não houver nenhum, retornará nulo.

Dessa forma, eu posso chamá-lo em qualquer lugar do aplicativo Rails, como por exemplo:

records = execute_statement("select * from table")

"execute_statement" também pode chamar procedimentos, funções e também visualizações de banco de dados do NuoDB.


3
é melhor usar exec_query se você estiver no PSQL porque ele
vazará

3
Não consigo encontrar a diferença entre o código na sua pergunta e na sua resposta. Ambos parecem usar ActiveRecord::Base.connection.execute. Você poderia apontar o que exatamente mudou para obter os dados em vez de apenas true?
precisa saber é o seguinte

119

Para mim, não consegui que isso retornasse um hash.

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

Mas o uso do método exec_query funcionou.

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

10
.exec_queryretorna um ActiveRecord::Resultobjeto que é muito útil, com fácil acesso .columnse .rowsatributos. .executeretorna uma matriz de hashes que geralmente é mais problemática e provavelmente mais pesada na memória. Eu nunca tinha usado exec_query, obrigado pela dica.
Francio Rodrigues

9
Apenas para adicionar ao último comentário, você normalmente deseja usar esse .entriesrecurso .exec_querypara obter os resultados como uma matriz de hashes.
8bithero

Isso sempre me dá nada para os resultados com o ActiveRecord 5 executando uma consulta DELETE?
Tom Rossi

27

Reposicionando a resposta do nosso fórum para ajudar outras pessoas com um problema semelhante:

@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 código acima é um exemplo para

  1. executando SQL arbitrário em sua conexão com o banco de dados
  2. retornando a conexão ao pool de conexão posteriormente

2
Por que você usará o pool de conexões em vez da própria conexão? Existe alguma vantagem? Você teria uma fonte sobre isso?
Bonafernando 23/05

3
@bonafernando, Seu banco de dados pode começar a gerar erros "Muitas conexões" se você tiver um código usado ActiveRecord::Base.connectionsem chamar ActiveRecord::Base.clear_active_connections!. Veja api.rubyonrails.org/v5.2/classes/ActiveRecord/…
eremite

Sim, antes da sua resposta eu mudei e notei que nunca tive outro erro "Conexões demais". Obrigado!
bonafernando
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.