dibi icon indicating copy to clipboard operation
dibi copied to clipboard

SqlsrvDriver: offset must have a order by

Open rumcais opened this issue 7 years ago • 5 comments

  • bug fix

rumcais avatar Jul 27 '18 19:07 rumcais

Limitations in Using OFFSET-FETCH ORDER BY is mandatory to use OFFSET and FETCH clause.

OFFSET clause is mandatory with FETCH. You can never use, ORDER BY … FETCH.

TOP cannot be combined with OFFSET and FETCH in the same query expression.

The OFFSET/FETCH rowcount expression can be any arithmetic, constant, or parameter expression that will return an integer value. The rowcount expression does not support scalar sub-queries.

https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx

rumcais avatar Jul 30 '18 09:07 rumcais

I think ORDER BY must be added by programmer, because he knows how to order rows. ORDER BY 1 solves nothing.

dg avatar Aug 01 '18 10:08 dg

But the queries you have in the tests do not pass to MSSQL. "SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY" ends with MSSQL error. Furthermore, FetchSingle() does not pass a simple query, and it does problems with addons like datagrid, etc.

rumcais avatar Aug 02 '18 06:08 rumcais

But the queries you have in the tests do not pass to MSSQL. "SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY" ends with MSSQL error.

So tests should be fixed, or not?

Furthermore, FetchSingle() does not pass a simple query, and it does problems with addons like datagrid, etc.

Can you send here example code?

dg avatar Aug 03 '18 08:08 dg

Perhaps we could throw an exception instead from SqlsrvDriver and PdoDriver (the sqlsrv case of applyLimit()) for SQL Server >= 2012, explaining that order must be specified in order to apply the limit? It fails with Incorrect syntax near '0' anyway, so it wouldn't cause a BC break.

I think that would be a good hint for simple cases like:

$dibi->select('*')->from('table')->fetch();

When I read this, I assume it does something like this:

SELECT TOP 1 * FROM [table]

ORDER BY 1 doesn't seem right to me, that might end up in getting an unexpected result, as you are sorting by first column of your query (from SELECT clause), which might be different from the default order (primary key).

If we don't want to force the programmer to order the query, fallback to SELECT TOP 1 ... might be a better option and might actually work without a subquery, since we don't need to offset the result.

ghost avatar Apr 10 '20 12:04 ghost