我正在使用带有CSqlDataProvider的分页。结果正确显示在分页的前20页或第一页。当我在网页上看到Log消息时,它使用的查询实际上是为所有页面选择前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..页的数据的查询。对于每一页,它都返回相同的数据,因为每次它都选择前20行。我不明白这种行为的原因。当您在分页期间使用SQL SERVER
作为DB,使用CSqlDataProvider
作为数据提供程序时,查询的实际外观如何?
我找到了解决方案。我不得不将CMssqlCommandBuilder中的rewriteLimitOffsetSql函数更改为:
return $sql." OFFSET ".$offset." ROWS FETCH NEXT ".$limit." ROWS ONLY";
只需函数中的这一行并删除其余代码。很高兴SQL SERVER开始支持OFFSET和FETCH。