为什么Rails(3 +)仍然不支持存储过程?
问题描述:
我熟悉Ruby on Rails,DB(MS)驱动程序和存储过程之间长久以来的爱恨关系,自从版本2.3.2开始,我一直在开发Rails应用程序。为什么Rails(3 +)仍然不支持存储过程?
但是,每隔一段时间就会出现一种情况,即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的设计选择?
答
轨道中支持存储过程。你得到的不同步错误是因为MySQL的MULTI_STATEMENTS
标志在默认情况下在Rails中未启用。该标志允许过程返回多于1个结果集。
在这里看到有关如何启用它的代码示例:https://gist.github.com/wok/1367987
存储过程制定出与MS SQL Server的盒子。
我一直在使用存储过程几乎所有我的MySQL和SQL Server的rails项目没有任何发布。
答
这是为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()中的列列表替换为模型列和存储过程结果中的列。我相信通过检查课程的专栏可以使其成为通用的。
答
那些获取同步错误的人可能会生成多个结果的过程。你需要做这样的事情来处理它们:
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')")
FWIW:从2006年2月,DHH采访时说:“我在花哨的功能,如存储过程完全不感兴趣,触发器之类的东西“ - http://dev.mysql.com/tech-resources/interviews/david-heinemeier-hansson-rails.html – 2012-07-25 19:36:21
另外[”我认为存储过程和限制恶劣和鲁莽的连贯驱逐舰“](http://web.archive.org/web/20060418215514/http://www.loudthinking.com/arc/000516.html)... – dbr 2012-07-25 19:39:01
2006 ...古代的原则(是的,6年是古老的在一个世界里e Rails)对于技术的发展很少有意义(640k就足够了,任何人都可以) 这里有理论和实践领域。理论上我绝对支持Rails范式,但有时候最好的规范化数据库会给现实世界带来最差的性能。 当一个SP可以在不到100ms的时间内为我的报告收集数据,并且通过Rails的方式完成这个过程需要2-3秒钟,并且多个查询在一个共享数据库中被触发时,我知道谁是明显的赢家。 – ChrisDekker 2012-07-25 19:50:41