0

CSqlDataProvider でページネーションを使用しています。ページネーションの最初の 20 ページまたは最初のページの結果が正しく表示されます。Web ページにログ メッセージが表示されると、クエリが実際にすべてのページの上位 20 行を選択していて、それが問題です。私はそれを修正する方法がわかりません。

私のコントローラーにはコードがあります:

public function actionLink()
 {
      $sql = "SELECT Ordernumber, Order_Date
                FROM [Orders]
                WHERE CAST(Order_Date As Date) BETWEEN '01-01-2014' AND '31-01-2014'";

      $count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM (' . $sql . ') as count_alias')->queryScalar();
      $dataProvider = new CSqlDataProvider($sql, array('keyField' => 'Order_Date',
           'totalItemCount' => $count,
           'pagination' => array(
           'pageSize' => 20,),));

      $this->render('link',  array('dataProvider' => $dataProvider));
    }}      

そして今、カウントに使用するクエリは正しいです (ログ メッセージ):

SQL のクエリ:

SELECT COUNT(*) FROM (SELECT Ordernumber ,Order_Date
FROM [Orders]
WHERE CAST(Order_Date As Date) BETWEEN '01-01-2014' AND '31-01-2014') as count_alias

ページ 2 に使用するクエリは次のとおりです (ログ メッセージ)。

 SELECT * FROM (SELECT TOP 20 * FROM (SELECT TOP 40 Ordernumber,Order_Date
 FROM [Orders]
 WHERE CAST(Order_Date As Date) 
 BETWEEN '01-01-2014' AND '31-01-2014') as [__inner__]) as [__outer__]

上記のクエリは、実際には最初の 20 行として結果を返します。どのページも同じ問題です。すべての結果が最初の 20 行と同じになります。したがって、ページ 3 は (ログ メッセージ) になります。

 SELECT * FROM (SELECT TOP 20 * FROM (SELECT TOP 60 Ordernumber,Order_Date
 FROM [Orders]
 WHERE CAST(Order_Date As Date) 
 BETWEEN '01-01-2014' AND '31-01-2014') 
 as [__inner__] ) as [__outer__]

私が見ることができる唯一の問題は、ページ 2、3 などのデータを取得するために使用しているクエリです。毎回TOP 20行を選択しているため、すべてのページで同じデータが返されます。この動作の理由がわかりません。SQL SERVERDBCSqlDataProviderとして使用し、ページネーション中にデータ プロバイダーとして使用する場合、クエリは実際にどのように見えますか?

4

1 に答える 1

2

解決策を見つけました。CMssqlCommandBuilder の rewriteLimitOffsetSql 関数を次のように変更する必要がありました。

return $sql." OFFSET ".$offset." ROWS FETCH NEXT ".$limit." ROWS ONLY";

関数内のこの 1 行だけを削除し、残りのコードを削除します。SQL SERVER が OFFSET と FETCH のサポートを開始したのは良いことです。

于 2014-05-02T14:25:55.117 に答える