我熟悉Ruby on Rails,DB(MS)驱动程序和存储过程之间长期以来爱恨交织的关系,我从版本2.3.2开始就开发了Rails应用程序。
但是,每隔一段时间出现一种情况,即SP只是比(慢得多)应用程序级别上的数据组合更好的选择。具体而言,运行组合来自多个表的数据的报告通常更适合SP。
为什么存储过程仍然很难集成到Rails或MySQL gem中。我目前正在开发一个使用Rails 3.0.10和MySQL2 gem 0.2.13的项目,但据我所知,即使是最新的Edge Rails和MySQL gem 0.3+,当你使用SP时仍然会发脾气。
问题一直是,现在仍然是,在调用SP后数据库连接丢失。
>> ActiveRecord::Base.connection.execute("CALL stored_proc")
=> #<Mysql::Result:0x103429c90>
>> ActiveRecord::Base.connection.execute("CALL stored_proc")
ActiveRecord::StatementInvalid: Mysql::Error: Commands out of sync;
[...]
>> ActiveRecord::Base.connection.active?
=> false
>> ActiveRecord::Base.connection.reconnect!
=> nil
>> ActiveRecord::Base.connection.execute("CALL proc01")
=> #<Mysql::Result:0x1034102e0>
>> ActiveRecord::Base.connection.active?
=> false
从技术上讲,这是一个非常难以解决的问题,还是Rails的设计选择?
答案 0 :(得分:10)
rails支持存储过程。您获得的不同步错误是因为在Rails中默认情况下未启用MySQL的MULTI_STATEMENTS
标志。此标志允许过程返回多于1个结果集。
请点击此处查看有关如何启用它的代码示例:https://gist.github.com/wok/1367987
存储过程与MS SQL Server一起开箱即用。
我几乎在所有基于mySQL和SQL Server的rails项目中都使用了存储过程而没有发布。
答案 1 :(得分:3)
这是为了让postgres执行一个返回MyClass实例的存储过程。
sql=<<-SQL
select * from my_cool_sp_with_3_parameters(?, ?, ?) as
foo(
column_1 <type1>,
column_2 <type2>
)
SQL
MyClass.find_by_sql([sql, param1, param2, param3]);
将foo()内的列列表替换为模型中的列和存储过程结果。我确信通过检查类的列可以使它成为通用的。
答案 2 :(得分:0)
获得同步错误的人可能会有生成多个结果的过程。你需要做这样的事情来处理它们:
raise 'You updated Rails. Check this duck punch is still valid' unless Rails.version == "3.2.15"
module ActiveRecord
module ConnectionAdapters
class Mysql2Adapter
def call_stored_procedure(sql)
results = []
results << select_all(sql)
while @connection.more_results?
results << @connection.next_result
end
results
end
end
end
end
这样打电话:
ActiveRecord::Base.connection.call_stored_procedure("CALL your_procedure('foo')")