Rasgele, uyumlu olarak mssql / mysql tarafından Zend_Db_Select sipariş

2 Cevap php

Tamam burada durum, ben Zend_Framework yazılmış bir uygulama var, o arka uç olarak MySQL ve MSSQL ile uyumludur. Şimdi, ZF iki dil arasındaki uyumsuzluklar SQL / farklılıkları bir çok çözme oldukça iyidir, ama ben yine de bu bir anlamaya henüz.

Amaç son derece basit bir ifadedir tablo 1 rasgele kaydını seçmektir.

Burada örneğin bir select ifadesi bulunuyor:

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

Bu, aşağıdaki gibi MySQL için sql, çünkü MySQL veritabanı tabloları için mükemmel çalışıyor:

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

Şimdi diğer taraftan MSSql, newid() işlev yapmak randomize etmek için kullanır.

Ben bunu doğru sıralamasını kullanmak zorunda olduğunu fark yapmak için order() fonksiyonu haline geçebilir yardımcısı çeşit var mı? Ben belgeleri aradı ve zfforums üzerinde, birkaç ipucu buldum, ama hiçbir şey katı.

Ben buldun şeylerden biriydi:

ORDER BY RANDOM() not working - ZFForums.com

Bunlar aşağıdaki kullanıyor:

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

Bu çalışıyor ... ama ben bunu yazarak ve bir dize yerine yaparak benim select ifadesi kurmak isteyen değilim, ben aynı Zend_Db_Select nesne tutmaya çalışıyorum. Ben de ekstresinde ->order() içine Zend_Db_Expr('RANDOM()') geçen denedim ve başarısız. O da cevap bulmak için bir teorik çözüm nakleder, ama ben $ db-> () çağrısı getirme değiştirerek, bu içinde işlevini yeniden yazmak için arıyorum değil.

Herhangi bir fikir?

2 Cevap

Bir tablo için işlevini hızla soyut olabilir - bu kullanarak hangi adaptörü bilir:

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();

Ayrıca, ben gibi bir şey çalışıyorum tavsiye olduğunu kaybetmiş bir yerde bir makale buldum:

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

MSSQL adlı sorgu iyileştirici yıkmak ve her satır için yeni bir değer hesaplanırken onu kandırmak için.

Ben sınıf My_Db_Expr_Rand Zend_Db_Expre uzanır yaratacaktır. Adaptör üzerinde bassed ben birini veya diğer ya dönecekti.