11

मैं रूबी, डीबी (एमएस) -ड्रिवर और संग्रहीत प्रक्रियाओं पर रुबी के बीच लंबे समय से प्यार-नफरत संबंध से परिचित हूं और मैं संस्करण 2.3.2 के बाद रेल अनुप्रयोग विकसित कर रहा हूं।रेल संग्रहीत प्रक्रियाओं को अभी भी रेल (3+) में क्यों समर्थित नहीं किया जाता है?

हालांकि, हर बार एक बार स्थिति उत्पन्न होती है जहां एक एसपी (बहुत धीमी) आवेदन स्तर पर डेटा संयोजन से बेहतर विकल्प है। विशेष रूप से, चल रही रिपोर्ट जो एकाधिक तालिकाओं से डेटा को जोड़ती है आमतौर पर एक एसपी के लिए बेहतर अनुकूल होती है।

संग्रहित प्रक्रियाएं अभी भी रेल या MySQL मणि में इतनी खराब रूप से एकीकृत क्यों हैं। मैं वर्तमान में रेल 3.0.10 और MySQL2 मणि ​​0.2.13 के साथ एक प्रोजेक्ट पर काम कर रहा हूं लेकिन जहां तक ​​मैं देख सकता हूं, नवीनतम एज रेल और MySQL मणि 0.3+ अभी भी एसपी का उपयोग करते समय टैंट्रम्स फेंक देते हैं।

समस्या जो अभी भी है, और अभी भी है, यह है कि एसपी के नाम के बाद डेटाबेस कनेक्शन खो जाता है।

>> 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 

क्या यह वास्तव में मुश्किल से निपटने में मुश्किल समस्या है, तकनीकी रूप से, या रेल द्वारा डिजाइन की पसंद है?

+0

FWIW: फरवरी 2006 से, DHH साक्षात्कार: "मैं संग्रहित प्रक्रियाओं की तरह आकर्षक सुविधाओं में पूरी तरह से रुचि नहीं कर रहा हूँ , ट्रिगर्स, और जैसे "- http://dev.mysql.com/tech-resources/interviews/david-heinemeier-hansson-rails.html –

+0

इसके अलावा [" मैं संग्रहीत प्रक्रियाओं और बाधाओं को समझता हूं और समेकन के बेकार विनाशक "] (http://web.archive.org/web/20060418215514/http://www.loudthinking.com/arc/000516.html) ... – dbr

+7

2006 ... प्राचीन सिद्धांत (हाँ, 6 साल प्राचीन है एक दुनिया की पसंद में ई रेल ') शायद ही कभी प्रौद्योगिकी के विकास के खिलाफ अर्थ रखता है (640k पर्याप्त है, कोई भी?) सैद्धांतिक और व्यावहारिक डोमेन है। सिद्धांत रूप में मैं बिल्कुल रेल प्रतिमान से खड़ा हूं, लेकिन कभी-कभी सर्वश्रेष्ठ सामान्यीकृत डेटाबेस वास्तविक दुनिया में सबसे खराब प्रदर्शन देता है। जब कोई एसपी 100 एमएमएस से कम समय में मेरी रिपोर्ट के लिए डेटा एकत्र कर सकता है और इसे 'रेल मार्ग' में 2-3 सेकंड से अधिक समय लेता है और साझा डेटाबेस पर कई प्रश्न निकाल दिए जाते हैं, तो मुझे पता है कि स्पष्ट विजेता कौन है। – ChrisDekker

उत्तर

10

संग्रहित प्रक्रिया रेल में समर्थित हैं। आपके द्वारा प्राप्त सिंक त्रुटि से बाहर है क्योंकि MULTI_STATEMENTS MySQL के लिए ध्वज डिफ़ॉल्ट रूप से रेल में सक्षम नहीं है। यह ध्वज 1 से अधिक परिणाम सेट को वापस करने की प्रक्रियाओं की अनुमति देता है।

इसे सक्षम करना पर एक कोड नमूने के लिए यहाँ देखें: https://gist.github.com/wok/1367987

संग्रहित प्रक्रियाओं एमएस SQL ​​सर्वर के साथ बॉक्स से बाहर काम करते हैं।

मैं बिना किसी जारी किए मेरे लगभग mySQL और SQL सर्वर आधारित रेल परियोजनाओं में संग्रहित प्रक्रियाओं का उपयोग कर रहा हूं।

3

यह संग्रहित प्रक्रिया निष्पादित करने के लिए पोस्टग्रेज़ के लिए है जो 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() के अंदर कॉलम सूची को बदलें। मुझे यकीन है कि कक्षा के कॉलम का निरीक्षण करके इसे सामान्य बनाया जा सकता है।

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')")