diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 9442b55f87d..cbf0cddb6d2 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -7,6 +7,7 @@ Yii Framework 2 Change Log - Bug #17413, #17418, #17426, #17431: Fixed MSSQL tests (alexkart) - Bug #17420: Fixed loading of column default values for MSSQL (alexkart) - Bug #17395: Fixed issues with actions that contain underscores in their names (alexkart) +- Bug #10023: Fixed MSSQL "There are no more rows in the active result set" exception when using `each()` and `batch()` (alexkart) 2.0.22 July 02, 2019 diff --git a/framework/db/BatchQueryResult.php b/framework/db/BatchQueryResult.php index 131e6de5034..ad543a0d9c2 100644 --- a/framework/db/BatchQueryResult.php +++ b/framework/db/BatchQueryResult.php @@ -66,7 +66,11 @@ class BatchQueryResult extends BaseObject implements \Iterator * @var string|int the key for the current iteration */ private $_key; - + /** + * @var string MSSQL exception that is thrown when last batch size less than specified batch size + * @see https://github.com/yiisoft/yii2/issues/10023 + */ + private $mssqlNoMoreRowsErrorMessage = 'SQLSTATE[IMSSP]: There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.'; /** * Destructor. @@ -140,8 +144,15 @@ protected function fetchData() $rows = []; $count = 0; - while ($count++ < $this->batchSize && ($row = $this->_dataReader->read())) { - $rows[] = $row; + + try { + while ($count++ < $this->batchSize && ($row = $this->_dataReader->read())) { + $rows[] = $row; + } + } catch (\PDOException $e) { + if ($e->getMessage() !== $this->mssqlNoMoreRowsErrorMessage) { + throw $e; + } } return $this->query->populate($rows); diff --git a/tests/framework/db/mssql/BatchQueryResultTest.php b/tests/framework/db/mssql/BatchQueryResultTest.php index ca123e59447..492373d72c1 100644 --- a/tests/framework/db/mssql/BatchQueryResultTest.php +++ b/tests/framework/db/mssql/BatchQueryResultTest.php @@ -7,8 +7,6 @@ namespace yiiunit\framework\db\mssql; -use yii\db\BatchQueryResult; - /** * @group db * @group mssql @@ -16,37 +14,4 @@ class BatchQueryResultTest extends \yiiunit\framework\db\BatchQueryResultTest { public $driverName = 'sqlsrv'; - private $noMoreRowsErrorMessage = 'SQLSTATE[IMSSP]: There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.'; - - protected function getAllRowsFromBach(BatchQueryResult $batch) - { - $allRows = []; - try { - foreach ($batch as $rows) { - $allRows = array_merge($allRows, $rows); - } - } catch (\PDOException $e) { - if ($e->getMessage() !== $this->noMoreRowsErrorMessage) { - throw $e; - } - } - - return $allRows; - } - - protected function getAllRowsFromEach(BatchQueryResult $each) - { - $allRows = []; - try { - foreach ($each as $index => $row) { - $allRows[$index] = $row; - } - } catch (\PDOException $e) { - if ($e->getMessage() !== $this->noMoreRowsErrorMessage) { - throw $e; - } - } - - return $allRows; - } }