1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-04 21:28:02 +02:00

SqlsrvDriver: added support for LIMIT & OFFSET on SQL Server 2012

This commit is contained in:
David Grudl
2015-10-26 18:08:36 +01:00
parent c26201c75d
commit 1333d07833
2 changed files with 25 additions and 16 deletions

View File

@@ -40,6 +40,9 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
/** @var int|FALSE Affected rows */
private $affectedRows = FALSE;
/** @var string */
private $version;
/**
* @throws Dibi\NotSupportedException
@@ -80,6 +83,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
$info = sqlsrv_errors();
throw new Dibi\DriverException($info[0]['message'], $info[0]['code']);
}
$this->version = sqlsrv_server_info($this->connection)['SQLServerVersion'];
}
@@ -297,13 +301,18 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function applyLimit(& $sql, $limit, $offset)
{
// offset support is missing
if ($limit >= 0) {
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') AS T ';
}
if (version_compare($this->version, 11, '<')) { // 11 == SQL Server 2012
if ($offset) {
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
if ($offset) {
throw new Dibi\NotImplementedException('Offset is not implemented.');
} elseif ($limit !== NULL) {
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
}
} elseif ($limit !== NULL || $offset) {
// requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx
$sql .= ' OFFSET ' . (int) $offset . ' ROWS '
. 'FETCH NEXT ' . (int) $limit . ' ROWS ONLY';
}
}

View File

@@ -40,28 +40,28 @@ $fluent = $conn->select('*')
->orderBy('customer_id');
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
(string) $fluent
);
$fluent->fetch();
Assert::same(
'SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T ',
'SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t',
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
$fluent->fetchAll(0, 3);
Assert::same(
reformat('SELECT TOP 3 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 3 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
(string) $fluent
);
@@ -69,16 +69,16 @@ Assert::same(
$fluent->limit(0);
$fluent->fetch();
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
(string) $fluent
);
@@ -87,12 +87,12 @@ $fluent->removeClause('limit');
$fluent->removeClause('offset');
$fluent->fetch();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) t'),
dibi::$sql
);
Assert::same(