Browse Source

Closes #10023. Fix MSSQL "There are no more rows" exception when using `each()` and `batch()`

tags/2.0.23
Alexander Kartavenko 5 years ago
parent
commit
25cf331839
  1. 1
      framework/CHANGELOG.md
  2. 17
      framework/db/BatchQueryResult.php
  3. 35
      tests/framework/db/mssql/BatchQueryResultTest.php

1
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

17
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 @@ class BatchQueryResult extends BaseObject implements \Iterator
$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);

35
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 @@ use yii\db\BatchQueryResult;
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;
}
}

Loading…
Cancel
Save