ZF-10831: Distinct statement doesn't work with basic limit in Zend_Db_Adapter_Sqlsrv

Description

I have found an error with basic limit statement if I use Zend_Db_Adapter_Sqlsrv as database adapter. Here is example:

 
$adapter = Zend_Registry::get('dbAdapter'); // Instance of Zend_Db_Adapter_Sqlsrv
$select = $adapter->select();

$select->distinct();
$select->from('Foo', array('FooID'));
$select->limit(5);
echo $select->__toString();

The result is following:

 
SELECT TOP 5 DISTINCT "Foo"."FooID" FROM "Foo"

But it produces database error. TOP have to be after DISTINCT.

 
SELECT DISTINCT TOP 5 "Foo"."FooID" FROM "Foo"

I'm using Zend Framework 1.11.1, Zend Server 5.0.2 (PHP 5.3.2), MSSQL 2005 Express.

Comments

The issue that you cannot use distinct() combined with a limit() clause in a select statement is still present in 1.11.4. I fixed it in our local installation with the following change (works in 1.11.3 and 1.11.4):

In Zend/Db/Adapter/Sqlsrv.php change line 616 from: $sql = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . $count . ' ', $sql);

to: $sql = preg_replace('/^(SELECT\sDISTINCT\s|SELECT\s)/i', '$0 TOP ' . $count . ' ', $sql);

This will place the DISTINCT keyword before the TOP keyword.

Same as above comment with pretty printing: from:



to:

In Zend/Db/Adapter/Sqlsrv.php change line 615: if ($offset == 0) { $sql = preg_replace('/^SELECT\s+(DISTINCT\s)?/i', 'SELECT TOP ' . $count . ' ', $sql); } else { to: $sql = preg_replace( '/^SELECT\s+(DISTINCT\s)?/i', 'SELECT $1TOP ' . ($count+$offset) . ' ', $sql ); if($offset > 0) {

Still not fixed in 1.11.11, over a year later.