Errore di SQL Server, "Utilizzo non valido dell'opzione PRIMA nell'istruzione FETCH".


8

Dal 2012 in poi i documenti di SQL Server mostrano che supportano quello OFFSET..FETCHche sto cercando di usare invece di a LIMIT.

Di seguito funziona perfettamente in PostgreSQL per campionare un set di risultati,

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;

Tuttavia, con SQL Server, ottengo

Msg 153, Level 15, State 2, Line 4
Invalid usage of the option FIRST in the FETCH statement.

Cosa sta succedendo qui? SQL Server supporta lo standardizzato OFFSET.. FETCH?

Risposte:


17

SQL Server ha implementato le clausole OFFSETe FETCHcome parte della ORDER BYclausola, come indicato dalle altre risposte e documentato nella loro documentazione.

Lo standard SQL dall'altra parte, ha entrambe queste clausole come indipendenti:

<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]

Se qualcuno desidera che questa funzionalità sia implementata nel pieno rispetto dello standard, può sempre fare una richiesta al team di SQL Server, attraverso il canale Connect. In effetti, MS ha commentato - in una diversa richiesta di offset e recupero:

Elemento di connessione: SQL Denali: aggiungi il contatore di righe totali SELECTall'istruzione - di Alexey Rokhin

Risposta: pubblicato da Microsoft il 24/11/2010 alle 11:34

Il requisito che OFFSET/FETCHrichiede ORDER BYè una limitazione in questa versione. Nello standard ANSI SQL (SQL: 2011) in cui OFFSET/FETCHvengono proposte le nuove clausole, ORDER BYè facoltativo. La limitazione in SQL Server ha a che fare con la limitazione della nostra tecnologia parser che non può gestire la sintassi opzionale senza creare OFFSETuna parola chiave riservata. Potremmo rimuoverlo in futuro.

Ora rispetto a ...

Fino ad allora, se si desidera utilizzare OFFSETe FETCHsenza uno specifico ORDER BY, una soluzione alternativa consiste nell'aggiungere una clausola ordine "non fare nulla". Esempio:

SELECT 
...
ORDER BY (SELECT NULL)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;

10

Come affermato all'inizio della documentazione su OFFSET..FETCH

La clausola OFFSET-FETCH offre un'opzione per recuperare solo una finestra o una pagina di risultati dal set di risultati. OFFSET-FETCH può essere utilizzato solo con la clausola ORDER BY.

...

ORDER BY è obbligatorio per utilizzare le clausole OFFSET e FETCH.

Così,

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
ORDER BY t.[x]  /* <-- ADD ME TO BE HAPPY */
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;

Non è poi così pratico per un semplice LIMITse è quello che stai cercando, ti consigliamo di rimanere con TOP.


9

Secondo il riferimento , la OFFSETclausola fa parte di ORDER BYSQL Server. Dovrai anche aggiungere la ROWSparola chiave dopo la OFFSETspecifica:

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
ORDER BY x
OFFSET 0 ROWS
FETCH FIRST 1 ROWS ONLY;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.