diff --git a/src/Dibi/Drivers/SqlsrvDriver.php b/src/Dibi/Drivers/SqlsrvDriver.php index b8bfd65b..f58b035d 100644 --- a/src/Dibi/Drivers/SqlsrvDriver.php +++ b/src/Dibi/Drivers/SqlsrvDriver.php @@ -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'; } } diff --git a/tests/dibi/Fluent.fetch.limit.mssql.phpt b/tests/dibi/Fluent.fetch.limit.mssql.phpt index 8a49075a..c0735b66 100644 --- a/tests/dibi/Fluent.fetch.limit.mssql.phpt +++ b/tests/dibi/Fluent.fetch.limit.mssql.phpt @@ -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(