2009-01-23 3 views
5

Wenn ich versuche, eine gespeicherte Prozedur von Rails zu nennen, bekomme ich diese Ausnahme:Ist es möglich, eine gespeicherte MySQL-Prozedur von Ruby aus aufzurufen?

ActiveRecord::StatementInvalid: Mysql::Error: PROCEDURE pipeline-ws_development.match_save_all can't return a result set in the given context: call match_save_all() 
    from /Users/otto/Projects/Futures/src/pipeline-ws/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:150:in `log' 
    from /Users/otto/Projects/Futures/src/pipeline-ws/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:281:in `execute' 
    from (irb):3 

Es gibt eine Seite im Rails Wiki that discusses a patch für den MySQL-Adapter, der dieses Problem behebt, aber es ist out-of-date und doesn Es scheint nicht mehr zu funktionieren.

Der Konfigurationscode aktiviert gespeicherte Prozeduren ordnungsgemäß, aber es besteht weiterhin das Problem, dass die Verbindung nach einem Aufruf der gespeicherten Prozedur nicht mehr synchron ist und die neue Methode call_sp nicht mehr funktioniert.

Irgendwelche Vorschläge, wie dies funktioniert?

Dies ist der Code Ich verwende:

ActiveRecord::Base.connection("call storedproc()") 

Es wirft die gleiche Ausnahme, ob storedproc() kehrt irgendwelche Ergebnisse oder nicht.

Antwort

1

Würde es funktionieren, die Prozedur in eine Funktion zu verpacken? Wenn Rubys barfing da keine Zeilen zurückgegeben (...can't return a result set in the given context...), kann dies beheben:

 
DELIMITER $ 

CREATE PROCEDURE tProc() 
BEGIN 
    SET @a = 'test'; 
END; 
$ 

CREATE FUNCTION tFunc() 
RETURNS INT 
BEGIN 
    CALL tProc(); 
    RETURN 1; 
END; 
$ 

DELIMITER ; 

SELECT tFunc() FROM DUAL; 
>> 1 

SELECT @a FROM DUAL; 
>> 'test' 

Obwohl, realistisch, dies nicht eine sehr erweiterbare Lösung.

Followup: Ich ziemlich n00by bei Ruby/Active bin, aber dieses Beispiel funktioniert auf jeden Fall

 
ActiveRecord::Base.establish_connection(authopts) 

class TestClass < ActiveRecord::Base 
end 

test_class = TestClass.new 
puts %{#{test_class.connection.select_one('SELECT tFunc() AS tf FROM DUAL')}} 
>> tf1 

Mit CALL tProc() in einem Fehler ähnlich wie bei Ihnen geführt.

+0

Ihr Beispiel funktioniert, aber mit unserer gespeicherten proc ich „ERROR 1415 (0A000): keine Ergebnismenge aus einer Funktion zurückkehren“. Ich werde mit dem Typen sprechen, der sie geschrieben hat, und sehen, ob wir sie nicht umschreiben können, um Dinge wie dein Beispiel zurückzugeben. – Otto

+1

Das bringt uns voran, aber wir haben immer noch ein paar Procs, die viele Daten zurückgeben müssen, die in Variablen nicht funktionieren. – Otto

+0

Ich ging voran und akzeptierte, da dies die beste aktuelle Lösung zu sein scheint. Es gibt immer noch das Problem, viele Daten zurückzugeben, aber es sind schon ein paar Tage vergangen und niemand hat sich etwas Besseres einfallen lassen. Ich glaube nicht, dass es existiert, ohne den MySQL-Adapter zu reparieren. – Otto

1

Verwenden Sie ActiveRecord :: Base.connection.execute? Mit dieser Methode können Sie eine beliebige SQL-Anweisung ausführen, die im Active Record-Wrapper nicht naiv unterstützt wird.

+1

Das ist, was ich benutze, und ich bekomme diese Ausnahme. – Otto

Verwandte Themen