2009-09-24 1 views
5

ここで状況はありますが、私はZend_Frameworkで書かれたアプリケーションを持っています。これはMySQLとMSSQLの両方とバックエンドとして互換性があります。さて、ZFは2つの言語のSQLの相違点/相違点の多くを解決するのにかなり良いですが、まだこれを理解していません。Zend_Db_Selectランダム、mssql/mysqlで互換性があります

目的は、テーブルから1つのランダムなレコードを選択することです。これは非常に単純なステートメントです。ここで

は、例えばselect文です:次のようにMySQLのSQLであるため

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

これは、MySQLデータベースのテーブルのために完璧に動作します:

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

今MSSQLは、一方で、 newid()関数を使用してランダム化を行います。

order()に渡すことができるヘルパーがありますか?適切な順序を使用しなければならないことを認識させるには?私はドキュメントとzfforumsを検索し、いくつかのヒントを見つけましたが、何もしっかりしていませんでした。私が見つけたものの

一つでした:

ORDER BY RANDOM() not working - ZFForums.com彼らが使用している

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

それは動作します...しかし、私はに見ているわけではありませんそれを入力して文字列を置換してselectステートメントを作成し、同じZend_Db_Selectオブジェクトにそのステートメントを保持しようとしています。私もZend_Db_Expr('RANDOM()')を文の->order()に渡そうとしましたが、失敗します。彼はまた、答えを見つけるための理論的な解決策を投稿しますが、私は$ db-> fetch()呼び出しを修正して、これが内部にある関数を書き直すつもりはありません。

アイデア?

答えて

14

- 誰がそれを使用しているアダプタを知っている:

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

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

はまた、私のような何かをしようとお勧めします、私は失われた記事のどこかを見つけました

MSSQLのクエリオプティマイザを無効にして、各行の新しい値を計算するようにトリックします。

2

クラスMy_Db_Expr_Randを作成し、Zend_Db_Exprを拡張します。アダプターをベースにして、どちらか一方を返すだろう。テーブルへの機能あなたは可能性が速く、抽象

+0

私はそれが好きですが、私はgnarfのアイデアがもう少し好きだと思います。テーブル抽象をランダム選択に拡張するだけでうまくいきます。 – Jesta

+0

はい、もちろんです。私のソリューションはより複雑で、あなたが作成したいものから来ています**表現は**アダプターに基づいています。だから、他のプロジェクトには一般的に再利用できます...しかし、私はテーブルソリューションがより簡単であることに同意します... –

+0

また、彼はDb_Exprを見せて、MSSQLとMySQLを変更せずに使用できるようにしました。一般的にどのプロジェクトにも再利用可能です。 – Jesta

関連する問題