Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

रेल में गतिशील रूप से प्रश्नों का निर्माण

आप अपने हैश के आधार पर एक SQL क्वेरी बना सकते हैं। सबसे सामान्य दृष्टिकोण कच्चा एसक्यूएल है, जिसे ActiveRecord . द्वारा निष्पादित किया जा सकता है ।

यहां कुछ अवधारणा कोड दिए गए हैं जो आपको सही विचार देंगे:

query_select = "select * from "
query_where = ""
tables = [] # for selecting from all tables
hash.each do |table, values|
  table_name = table.constantize.table_name
  tables << table_name
  values.each do |q|
    query_where += " AND " unless query_string.empty?
    query_where += "'#{ActiveRecord::Base.connection.quote(table_name)}'."
    query_where += "'#{ActiveRecord::Base.connection.quote(q[fieldName)}'"
    if q[:operator] == "starts with" # this should be done with an appropriate method
      query_where += " LIKE '#{ActiveRecord::Base.connection.quote(q[val)}%'"
    end
  end
end
query_tables = tables.join(", ")
raw_query = query_select + query_tables + " where " + query_where 
result = ActiveRecord::Base.connection.execute(raw_query)
result.to_h # not required, but raw results are probably easier to handle as a hash

यह क्या करता है:

  • query_select निर्दिष्ट करता है कि आपको परिणाम में कौन सी जानकारी चाहिए
  • query_where सभी खोज स्थितियों को बनाता है और SQL इंजेक्शन को रोकने के लिए इनपुट से बच निकलता है
  • query_tables उन सभी तालिकाओं की एक सूची है जिन्हें आपको खोजने की आवश्यकता है
  • table_name = table.constantize.table_name आपको SQL table_name देगा जैसा कि मॉडल द्वारा उपयोग किया गया है
  • raw_query उपरोक्त भागों से वास्तविक संयुक्त sql क्वेरी है
  • ActiveRecord::Base.connection.execute(raw_query) डेटाबेस पर sql निष्पादित करता है

सुनिश्चित करें कि उपयोगकर्ता द्वारा सबमिट किए गए इनपुट को उद्धरणों में डालें और SQL इंजेक्शन को रोकने के लिए इसे ठीक से छोड़ दें।

आपके उदाहरण के लिए बनाई गई क्वेरी इस तरह दिखेगी:

select * from companies, categories where 'companies'.'name' LIKE 'a%' AND 'companies'.'hq_city' = 'karachi' AND 'categories'.'name' NOT LIKE '%ECommerce%'

संबंधित तालिकाओं में शामिल होने के लिए इस दृष्टिकोण को अतिरिक्त तर्क की आवश्यकता हो सकती है। आपके मामले में, यदि company और category एक जुड़ाव है, आपको query_where . में कुछ इस तरह जोड़ना होगा

"AND 'company'.'category_id' = 'categories'.'id'"

आसान तरीका: आप मॉडल/टेबल के सभी जोड़े के लिए हैश बना सकते हैं जिन्हें पूछताछ की जा सकती है और वहां उचित जॉइन कंडीशन स्टोर कर सकते हैं। मध्यम आकार के प्रोजेक्ट के लिए भी यह हैश बहुत जटिल नहीं होना चाहिए।

कठिन दृष्टिकोण: यह स्वचालित रूप से किया जा सकता है, यदि आपके पास has_many . है , has_one और belongs_to आपके मॉडल में ठीक से परिभाषित किया गया है। आप reflect_on_all_associations<का उपयोग करके मॉडल की संबद्धता प्राप्त कर सकते हैं। /ए> . एक Breath-First-Search लागू करें या Depth-First Search एल्गोरिदम और किसी भी मॉडल से शुरू करें और अपने जेसन इनपुट से अन्य मॉडलों से मेल खाने वाले संघों की खोज करें। नए BFS/DFS रन तब तक शुरू करें जब तक कि json इनपुट से कोई अनविजिटेड मॉडल न बचे। मिली जानकारी से, आप सभी शामिल होने की शर्तें प्राप्त कर सकते हैं और फिर उन्हें where . में एक्सप्रेशन के रूप में जोड़ सकते हैं कच्चे एसक्यूएल दृष्टिकोण का खंड जैसा कि ऊपर बताया गया है। इससे भी अधिक जटिल, लेकिन करने योग्य भी डेटाबेस schema . को पढ़ना होगा और foreign keys . की तलाश में यहां परिभाषित समान दृष्टिकोण का उपयोग करते हुए ।

संघों का उपयोग करना: यदि वे सभी has_many . से संबद्ध हैं / has_one , आप ActiveRecord . के साथ जुड़ने को संभाल सकते हैं joins . का उपयोग करके inject के साथ विधि इस तरह "सबसे महत्वपूर्ण" मॉडल पर:

base_model = "Company".constantize
assocations = [:categories]  # and so on
result = assocations.inject(base_model) { |model, assoc| model.joins(assoc) }.where(query_where)

यह क्या करता है:

अस्वीकरण आपके द्वारा उपयोग किए जाने वाले SQL कार्यान्वयन के आधार पर आपके लिए आवश्यक सटीक सिंटैक्स भिन्न हो सकता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक दूसरे के भीतर सबक्वेरी को नेस्ट करके MySQL में 61 टेबल जॉइन लिमिट के आसपास काम करें

  2. क्या मुझे mysql_close (कनेक्शन) का उपयोग करने की आवश्यकता है?

  3. कॉलम नामों को लोअरकेस में बदलने के लिए एक MYSQL स्क्रिप्ट

  4. संग्रहीत प्रक्रिया के माध्यम से दिन प्रदर्शित करें

  5. MySQL Sum कॉलम IF ID किसी अन्य तालिका क्वेरी में है