Yii Pagination Result с использованием CSqlDataProvider

Я использую нумерацию страниц с CSqlDataProvider. Результат отображается правильно для первых 20 или первой страницы нумерации страниц. Когда я вижу сообщение "Журнал" на веб-странице, запрос, который он использует, фактически выбирает 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));
    }}      

И теперь запрос, который он использует для подсчета, является правильным (Log Message):

Запрос 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 как БД и CSqlDataProvider как поставщик данных во время нумерации страниц?

1 ответ

Решение

Я нашел решение. Мне пришлось изменить функцию rewriteLimitOffsetSql в CMssqlCommandBuilder на:

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

Просто эту одну строку в функции и удалите оставшуюся часть кода. Хорошо, что SQL SERVER начал поддержку OFFSET и FETCH.

Другие вопросы по тегам