2010-10-26 11 views
5

मैं इस तरह प्रश्न हैं:वाईआई ढांचे में जटिल क्वेरी के साथ मानदंड कैसे बनाएं?

SELECT * FROM activity 
WHERE (((userId = 1 OR userId IN(SELECT userId FROM follower WHERE followerId = 1)) 
AND activityType IN(1, 2, 3)) 
OR (targetId = 24 AND aType IN(1, 2, 3, 4, 5))) 
ORDER BY id DESC; 

मैं model()->findAllBySql($sql) इस्तेमाल करने की कोशिश की है और यह काम करता है। लेकिन मैं इसे CDbCriteria का उपयोग करना चाहता हूं, यदि आपके पास अन्य समाधान हैं तो मुझे यह बताएं: डी

+1

थोड़ा पुराना सवाल है लेकिन मुझे टिप्पणी करने की आवश्यकता है। जटिल प्रश्नों से निपटने पर ** ** किसी भी ओआरएम का उपयोग न करें। आपको शुद्ध एसक्यूएल से निपटना होगा (एआर एक 'findAllBySql()' विधि प्रदान करता है)। –

+0

@Andrzej Ośmiałowski क्या आप हमें कारण दे सकते हैं कि हमें ORM (मानदंड) का उपयोग करने के बजाय findAllBySql का उपयोग क्यों करना चाहिए। – aslingga

उत्तर

7

आप अभी भी एक CDbCriteria मुझे लगता है कि के साथ इस बयान का निर्माण कर सकता है ... कुछ की तरह:

$criteria=new CDbCriteria; 
$criteria->condition = ' 
    (
    (
     userId = 1 OR 
     userId IN (SELECT userId FROM follower WHERE followerId = 1) 
    ) 
    AND activityType IN(1, 2, 3) 
) 
    OR (
    targetId = 24 
    AND aType IN(1, 2, 3, 4, 5) 
) 
'; 
$criteria->order = 'id DESC'; 
$results=Activity::model()->findAll($criteria); 

इस बिंदु तुम भी सिर्फ एक नियमित रूप से एसक्यूएल बयान में लिख सकते हैं, लेकिन वहाँ करने के लिए कुछ लाभ हो सकता है के रूप में यह इस तरह से: बाध्यकारी पैरामीटर, मापदंड विलय, अतिरिक्त मापदंड जोड़ने, आदि

6

जब तक आपका सादा एसक्यूएल काम करता है, तो आप सुरक्षित हैं। कई बार जब मुझे सक्रिय रिकॉर्ड को फेंकना पड़ता है और ओल 'सैनर तरीके से काम पूरा हो जाता है।

मैंने इस क्वेरी को एक पठनीय सीडीबीक्रिटिया निर्माण में अनुवाद करने का प्रयास किया। बुरा विचार। जटिल डेटा पूछने की बात आती है जब Yii बेकार है।

+0

धन्यवाद @pestaa, मुझे आशा है कि वाईआई जटिल क्वेरी के लिए समाधान देगी: डी – aslingga

+1

@aslingga यह मूल रूप से "गलत डिज़ाइन" है। मैं नहीं कह रहा हूं कि मैं बेहतर कर सकता हूं, हालांकि। – pestaa

+0

थोड़ी देर बाद, लेकिन 5 साल बाद, आप किस फ्रेमवर्क की सिफारिश करेंगे? – Tebe

1

जवाब यहां पाया जा सकता है: http://www.yiiframework.com/doc/guide/1.1/en/database.dao#executing-sql-statements

आपके मामले में:

$sql = 'SELECT * FROM activity'; 
$sql .= 'WHERE (((userId = 1 OR userId IN(SELECT userId FROM follower WHERE followerId = 1))'; 
$sql .= 'AND activityType IN(1, 2, 3))'; 
$sql .= 'OR (targetId = 24 AND aType IN(1, 2, 3, 4, 5)))'; 
$sql .= 'ORDER BY id DESC'; 

$connection = Yii::app()->db; 
$command = $connection->createCommand($sql); 
$results = $command->queryAll(); 

@pestaa सही है कि कभी कभी यह है कि आप खिड़की से बाहर सक्रिय रिकॉर्ड फेंक करने के लिए है। यह विशेष रूप से सच है यदि आप बड़े पैमाने पर अपडेट कर रहे हैं जहां कई मॉडलों के माध्यम से लूपिंग बेहद अक्षम है।

+0

आपके समाधान के लिए @ फिलिप धन्यवाद। लेकिन अब मैं अपने सक्रिय रिकॉर्ड में सीडीबीक्रिटारिया का उपयोग करना चाहता हूं। मैंने एसक्यूएल का उपयोग करने और गतिविधि :: मॉडल() -> findAllBySql ($ sql) का उपयोग करके निष्पादित करने का प्रयास किया है और मुझे लगता है कि यह SQL Comamnd का उपयोग करने के समान परिणाम देगा। : डी – aslingga

+0

@aslingga, सीडीबीक्रिटिया का उपयोग करने और इस तरह के बयान को बनाने के बारे में आपका प्रश्न है? यदि ऐसा है, तो मुझे बताएं और शायद मैं मदद कर सकता हूं। सीडीबीक्रिटिरिया के फायदों में से एक यह बाध्य पैरामीटर को शामिल करता है, जो कि यदि आप उपयोगकर्ता इनपुट के साथ पूछताछ कर रहे हैं तो एसक्यूएल इंजेक्शन को रोकने में आवश्यक है। मैंने उपरोक्त आपके कथन की कोशिश नहीं की है, लेकिन मुझे कोई कारण नहीं दिखता कि यह क्यों काम नहीं करेगा। –

+0

मैं इसे वाईआई में सीपीनेशन के साथ जोड़ना चाहता हूं, क्या इसे संभव बनाने के लिए कोई तरीका है? – aslingga

0

बस CSqlDataProvider http://www.yiiframework.com/doc/api/1.1/CSqlDataProvider

अस्वीकरण का उपयोग करें: मैं जानता हूँ कि यह इस particural क्ष को सटीक जवाब नहीं है उत्पीड़न लेकिन यह दिया गया था कि समस्या के आसपास काम करने में मदद कर सकता है। मुझे संदेह है कि इस सवाल का मुख्य उद्देश्य मनमाने ढंग से एसक्यूएल के साथ CGridView, CListView आदि का उपयोग करने का तरीका हो रहा है।

0

मैं जटिल प्रश्नों के लिए CDbCriteria का उपयोग करता हूं जिसमें मैं with सुविधा का उपयोग करता हूं।

आप इस तरह जटिल मापदंड का निर्माण कर सकते हैं:

$dbCriteria->with=array(
    '<relation1>'=>array('condition'=>'<condition for given relation>', 
     'with'=>array('<relation2:relation of relation1>' 
      =>array(<conditions for relation2>) 
     ) 
     'scopes'=><scopes for relation1> 
    ) 
); 

मैं जाँच नहीं की है कि कैसे OR खेलने में यहाँ मिल सकती है।

स्कॉप्स का उपयोग करके, आप कुछ और जटिल मानदंड भी डाल सकते हैं और फिर भी अपनी खोज स्थिति को पठनीय रख सकते हैं।

यह बहुत शक्तिशाली है। मुझे अभी तक इस बारे में एक पूर्ण 'ट्यूटोरियल' नहीं मिला; मैं इस तरह से स्रोत कोड से निष्कर्ष निकाला।

+0

क्या आप एक उदाहरण जोड़ सकते हैं? मैं समझ नहीं पा रहा हूं कि वास्तविक जीवन में इसे कैसे क्लोन करें – realtebo

संबंधित मुद्दे