Yii分页结果使用CSqlDataProvider

时间:2014-04-30 13:20:52

标签: php gridview yii pagination csqldataprovider

我正在使用CSqlDataProvider进行分页。分页的前20页或第1页正确显示结果。当我在网页上看到日志消息时,它使用的查询实际上是为所有页面选择前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 SERVER作为数据库和CSqlDataProvider作为数据提供者时,查询的实际情况如何?

1 个答案:

答案 0 :(得分:2)

我找到了解决方案。 我不得不将CMssqlCommandBuilder中的rewriteLimitOffsetSql函数更改为:

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

在功能中只有这一行并删除其余的代码。很好,SQL SERVER开始支持OFFSET和FETCH。