Wie können Sie SQL-Befehle in Ruby On Rails mithilfe von NuoDB manuell ausführen?


142

Ich versuche, SQL-Befehle manuell auszuführen, damit ich auf Prozeduren in NuoDB zugreifen kann.

Ich verwende Ruby on Rails und verwende den folgenden Befehl:

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

Die "SQL-Abfrage" kann ein beliebiger SQL-Befehl sein.

Wie zum Beispiel habe ich eine Tabelle namens "Feedback" und wenn ich den Befehl ausführe:

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

Dies würde nur eine "wahre" Antwort zurückgeben, anstatt mir alle angeforderten Daten zu senden.

Dies ist die Ausgabe auf der Rails Console:

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

Ich möchte dies verwenden, um gespeicherte Prozeduren in NuoDB aufzurufen, aber beim Aufrufen der Prozeduren würde dies auch eine "wahre" Antwort zurückgeben.

Kann ich trotzdem SQL-Befehle ausführen und die angeforderten Daten abrufen, anstatt eine "echte" Antwort zu erhalten?

Antworten:


166

Der Arbeitsbefehl, mit dem ich benutzerdefinierte SQL-Anweisungen ausführe, lautet:

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

wobei "foo" die SQL-Anweisung ist (dh "SELECT * FROM table").

Dieser Befehl gibt eine Reihe von Werten als Hash zurück und fügt sie in die Ergebnisvariable ein.

Also habe ich auf meinen Schienen application_controller.rb Folgendes hinzugefügt:

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

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

Wenn Sie execute_statement verwenden, werden die gefundenen Datensätze zurückgegeben. Wenn keine vorhanden sind, wird null zurückgegeben.

Auf diese Weise kann ich es einfach überall in der Rails-Anwendung aufrufen, wie zum Beispiel:

records = execute_statement("select * from table")

"execute_statement" kann auch NuoDB-Prozeduren, -Funktionen und auch Datenbankansichten aufrufen.


3
Es ist besser, exec_query zu verwenden, wenn Sie unter PSQL arbeiten, da dadurch Speicher verloren geht
23inhouse

3
Ich kann den Unterschied zwischen dem Code in Ihrer Frage und in Ihrer Antwort nicht finden. Sie scheinen beide zu benutzen ActiveRecord::Base.connection.execute. Könnten Sie bitte darauf hinweisen, was genau Sie geändert haben, um die Daten zu erhalten, anstatt nur true?
RocketR

119

Für mich konnte ich das nicht dazu bringen, einen Hash zurückzugeben.

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

Die Verwendung der exec_query-Methode hat jedoch funktioniert.

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

10
.exec_queryGibt ein ActiveRecord::ResultObjekt zurück, das mit leicht zugänglichen Attributen .columnsund .rowsAttributen sehr praktisch ist . .executeGibt eine Reihe von Hashes zurück, die normalerweise schwieriger zu handhaben sind und wahrscheinlich mehr Speicher benötigen. Ich hatte noch nie benutzt exec_query, danke für den Tipp.
Francio Rodrigues

9
Nur um den letzten Kommentar hinzuzufügen, möchten Sie normalerweise .entriesverwenden .exec_query, um die Ergebnisse als Array von Hashes abzurufen.
8bithero

Dies gibt mir immer null für die Ergebnisse, wenn ActiveRecord 5 eine DELETE-Abfrage ausführt.
Tom Rossi

27

Reposting der Antwort aus unserem Forum, um anderen bei einem ähnlichen Problem zu helfen:

@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;" ) }

Der obige Code ist ein Beispiel für

  1. Ausführen von beliebigem SQL auf Ihrer Datenbankverbindung
  2. Anschließend wird die Verbindung wieder in den Verbindungspool zurückgeführt

2
Warum verwenden Sie den Verbindungspool anstelle der Verbindung selbst? Gibt es einen Vorteil? Hättest du eine Quelle dazu?
Bonafernando

3
@bonafernando, Ihre Datenbank kann Fehler "Zu viele Verbindungen" auslösen, wenn Sie Code haben, der ActiveRecord::Base.connectionohne Aufruf verwendet wird ActiveRecord::Base.clear_active_connections!. Siehe api.rubyonrails.org/v5.2/classes/ActiveRecord/...
eremite

Ja, vor Ihrer Antwort habe ich mich geändert und festgestellt, dass ich noch nie einen anderen Fehler "Zu viele Verbindungen" hatte. Vielen Dank!
Bonafernando
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.