2009-09-24 14 views
5

में संगत, ठीक है, यहां स्थिति है, मेरे पास Zend_Framework में लिखा गया एक एप्लीकेशन है, जो बैकएंड के रूप में MySQL और MSSQL दोनों के साथ संगत है। अब, जेडएफ दो भाषाओं के बीच कई एसक्यूएल विसंगतियों/मतभेदों को हल करने में बहुत अच्छा है, लेकिन मुझे अभी भी इसे अभी तक समझना बाकी नहीं है।यादृच्छिक रूप से Zend_Db_Select ऑर्डर, mssql/mysql

उद्देश्य तालिका से 1 यादृच्छिक रिकॉर्ड चुनना है, जो एक बेहद सरल कथन है। ,

$sql = $db->select() 
     ->from("table") 
     ->order("rand()") 
     ->limit(1); 

यह MySQL डेटाबेस तालिकाओं के लिए पूरी तरह से काम करता है क्योंकि MySQL के लिए एसक्यूएल इस प्रकार है::

यहाँ उदाहरण के लिए एक का चयन करें बयान है, दूसरे हाथ पर

SELECT `table`.* FROM `table` ORDER BY rand() ASC 

अब MSSQL यादृच्छिक करने के लिए newid() फ़ंक्शन का उपयोग करता है।

क्या कुछ प्रकार का सहायक है, मैं ऑर्डर() फ़ंक्शन में पास कर सकता हूं ताकि यह महसूस किया जा सके कि इसे उचित क्रम का उपयोग करना है? मैंने प्रलेखन की खोज की और zfforums पर, कुछ सुझाव मिले, लेकिन कुछ ठोस नहीं है।

चीजें मैं मिला था:

ORDER BY RANDOM() not working - ZFForums.com

वे उपयोग कर रहे हैं निम्नलिखित:

$res = $db->fetchAll(
'SELECT * FROM table ORDER BY :random', 
array('random' => new Zend_Db_Expr('RANDOM()') 
); 

यह काम करता है ... लेकिन मैं करने के लिए देख नहीं कर रहा हूँ इसे टाइप करके और स्ट्रिंग पर प्रतिस्थापन करके मेरा चयन कथन बनाएं, मैं इसे उसी Zend_Db_Select ऑब्जेक्ट में रखने की कोशिश कर रहा हूं। मैंने कथन पर ->order() में Zend_Db_Expr('RANDOM()') में गुजरने का प्रयास किया है, और यह विफल हो जाता है। वह जवाब खोजने के लिए एक सैद्धांतिक समाधान भी पोस्ट करता है, लेकिन मैं $ db-> fetch() कॉल को संशोधित करने के भीतर उस फ़ंक्शन को फिर से लिखना नहीं चाहता हूं।

कोई विचार?

उत्तर

14

आप कर सकते थे जल्दी से सार एक मेज के समारोह - कौन जानता है जो एडाप्टर यह उपयोग कर रहा है:

class MyTable extends Zend_Db_Table_Abstract { 
    public function randomSelect($select=null) { 
    if ($select === null) $select = $this->select(); 
    if (!$select instanceOf Zend_Db_Select) $select = $this->select($select); 
    $adapter = $this->getAdapter(); 
    if ($adapter instanceOf Zend_Db_Adapter_Mysqli) { 
     $select->order(new Zend_Db_Expr('RAND()')); 
    } else if ($adapter instanceOf Zend_Db_Adapter_Dblib) { 
     $select->order(new Zend_Db_Expr('NEWID()')); 
    } else { 
     throw new Exception('Unknown adapter in MyTable'); 
    } 
    return $select; 
    } 
} 

$someSelect = $table->select(); 
// add it to an existing select 
$table->randomSelect($someSelect); 

// or create one from scratch 
$select = $table->randomSelect(); 

इसके अलावा, मैंने पाया कहीं एक लेख जो मैं हार ऐसा ही कुछ कोशिश कर की सिफारिश की:

$select->order(new Zend_Db_Expr('0*`id`+RAND())); 

MSSQL के क्वेरी ऑप्टिमाइज़र को हटाने के लिए और प्रत्येक पंक्ति के लिए एक नए मान की गणना करने के लिए इसे चालित करें।

2

मैं कक्षा बनाना होगा My_Db_Expr_Rand Zend_Db_Expr को बढ़ाता है। एडाप्टर पर लगाए गए मैं एक या दूसरे को वापस कर दूंगा।

+0

मुझे यह पसंद है, लेकिन मुझे लगता है कि मुझे gnarf के विचार को थोड़ा और पसंद है। यादृच्छिक चयन के लिए टेबल सार को विस्तारित करना बहुत अच्छा काम करता है। – Jesta

+0

हां, ज़ाहिर है। मेरा समाधान अधिक जटिल है और उस चीज से आता है जिसे आप एक एडाप्टर के आधार पर ** एक अभिव्यक्ति ** बनाना चाहते हैं। तो यह आम तौर पर किसी भी अन्य परियोजना के लिए पुन: प्रयोज्य है ... लेकिन मैं मानता हूं कि तालिका समाधान अधिक सरल है ... –

+0

नीचे उन्होंने डीबी_एक्सआरपी भी दिखाया है जिसका उपयोग आप एमएसएसएलएल और माईएसक्यूएल के लिए इसे संशोधित किए बिना कर सकते हैं, इसे होने देना आम तौर पर किसी भी परियोजना के लिए पुन: प्रयोज्य। – Jesta

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