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.