223

I'm trying to manually execute SQL commands so I can access procedures in NuoDB.

I'm using Ruby on Rails and I'm using the following command:

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

The "SQL query" could be any SQL command.

For example, I have a table called "Feedback" and when I execute the command:

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

This would only return a "true" response instead of sending me all the data requested.

This is the output on the Rails Console is:

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

I would like to use this to call stored procedures in NuoDB but upon calling the procedures, this would also return a "true" response.

Is there any way I can execute SQL commands and get the data requested instead of getting a "true" response?

5 Answers 5

251

The working command I'm using to execute custom SQL statements is:

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

with "foo" being the sql statement( i.e. "SELECT * FROM table").

This command will return a set of values as a hash and put them into the results variable.

So on my rails application_controller.rb I added this:

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

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

Using execute_statement will return the records found and if there is none, it will return nil.

This way I can just call it anywhere on the rails application like for example:

records = execute_statement("select * from table")

"execute_statement" can also call NuoDB procedures, functions, and also Database Views.

Sign up to request clarification or add additional context in comments.

4 Comments

it's better to use exec_query if you are on PSQL because it will leak memory
I cannot find the difference between the code in your question and in your answer. They both seem to use ActiveRecord::Base.connection.execute. Could you please point out what exactly you changed to get the data instead of just true?
I'm guessing the difference is that ActiveRecord::Base.connection.execute is now assigned to results
This is completely useless - I guess OP is karma farming.
195

For me, I couldn't get this to return a hash.

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

But using the exec_query method worked.

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

3 Comments

.exec_query returns an ActiveRecord::Result object which is very handy with easily accessible .columns and .rows attributes. .execute returns an array of hashes which is usually more troublesome to deal with and probably heavier on memory. I had never used exec_query, thanks for the tip.
Just to add to the last comment, you'd typically want to use .entries when using .exec_query to get the results as an array of hashes.
This always gives me nil for the results with ActiveRecord 5 running a DELETE query?
47

Reposting the answer from our forum to help others with a similar issue:

@connection = ActiveRecord::Base.connection
result = @connection.exec_query('select tablename from system.tables')
result.each do |row|
puts row
end

Comments

30
res = ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query( "SELECT 1;" ) }

The above code is an example for

  1. executing arbitrary SQL on your database-connection
  2. returning the connection back to the connection pool afterwards

3 Comments

Why will you use the connection pool instead of the connection itself? Is there any advantage? Would you have a source about it?
@bonafernando, Your database might start throwing "Too many connections" errors if you have code that uses ActiveRecord::Base.connection without calling ActiveRecord::Base.clear_active_connections!. See api.rubyonrails.org/v5.2/classes/ActiveRecord/…
Yeah, before your answer I've changed and noticed I've never had any other "Too many connections" error. Thanks!
13

Once you get the MySql::Result object

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

You can convert it to array of rows

results.to_a

will make array of this format

[[row1][row2]...]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.