Datenbank.Anleitung

Die Paginierung wird häufig in Anwendungen verwendet, bei denen der Benutzer auf Zurück / Weiter klicken kann, um durch die Seiten zu navigieren, aus denen die Ergebnisse bestehen, oder auf eine Seitenzahl klicken kann, um direkt zu einer bestimmten Seite zu gelangen.

Wenn Sie Abfragen in SQL Server ausführen, können Sie die Ergebnisse paginieren, indem Sie die OFFSET und FETCH Argumente der ORDER BY Klausel verwenden. Diese Argumente wurden in SQL Server 2012 eingeführt, daher können Sie diese Technik verwenden, wenn Sie über SQL Server 2012 oder höher verfügen.

In diesem Zusammenhang teilen Sie die Abfrageergebnisse bei der Paginierung in kleinere Blöcke auf, wobei jeder Block dort fortgesetzt wird, wo der vorherige beendet wurde. Wenn eine Abfrage beispielsweise 1000 Zeilen zurückgibt, können Sie sie so paginieren, dass sie in Gruppen von 100 zurückgegeben werden. Eine Anwendung kann die Seitenzahl und die Seitengröße an SQL Server übergeben, und SQL Server kann sie dann verwenden, um nur die Daten für die angeforderte Seite zurückzugeben.

Beispiel 1 – Keine Paginierung

Lassen Sie uns zunächst eine Abfrage ausführen, die alle Zeilen in einer Tabelle zurückgibt:

SELECT *FROM GenresORDER BY GenreId;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country || 4 | Pop || 5 | Blues || 6 | Hip Hop || 7 | Rap || 8 | Punk |+-----------+---------+

Dieses Beispiel verwendet keine Paginierung – alle Ergebnisse werden angezeigt.

Diese Ergebnismenge ist so klein, dass normalerweise keine Paginierung erforderlich ist, aber für die Zwecke dieses Artikels sollten wir sie paginieren.

Beispiel 2 – Anzeige der ersten 3 Ergebnisse

In diesem Beispiel werden die ersten drei Ergebnisse angezeigt:

SELECT *FROM GenresORDER BY GenreId OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+

In diesem Fall gebe ich an, dass die Ergebnisse beim ersten Ergebnis beginnen und die nächsten drei Zeilen anzeigen sollen. Dies geschieht mit folgendem:

  • OFFSET 0 ROWS gibt an, dass kein Offset (ein Offset von Null) vorhanden sein soll.
  • FETCH NEXT 3 ROWS ONLY ermittelt die nächsten drei Zeilen aus dem Offset. Da ich einen Versatz von Null angegeben habe, werden die ersten drei Zeilen abgerufen.

Wenn wir nur die Top-3-Ergebnisse wollten, hätten wir das gleiche Ergebnis erzielen können, indem wir die TOP Klausel verwendet hätten, anstatt die Offset- und fetch-Werte anzugeben. Dies hätte uns jedoch nicht erlaubt, den nächsten Teil zu machen.

Beispiel 3 – Anzeige der nächsten 3 Ergebnisse

Lassen Sie uns nun die nächsten drei Ergebnisse anzeigen:

SELECT *FROM GenresORDER BY GenreId OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 4 | Pop || 5 | Blues || 6 | Hip Hop |+-----------+---------+

Das einzige, was ich geändert habe, war der Offset.

Die Offset- und Abrufwerte können auch ein Ausdruck sein, der als Variable, Parameter oder konstante skalare Unterabfrage bereitgestellt wird. Wenn eine Unterabfrage verwendet wird, kann sie nicht auf Spalten verweisen, die im Bereich der äußeren Abfrage definiert sind (sie kann nicht mit der äußeren Abfrage korreliert werden).

Die folgenden Beispiele verwenden Ausdrücke, um zwei Ansätze zum Paginieren der Ergebnisse zu zeigen.

Beispiel 4 – Paginierung nach Zeilennummer

In diesem Beispiel werden Ausdrücke verwendet, um die Zeilennummer anzugeben, mit der begonnen werden soll.

DECLARE @StartRow int = 1, @RowsPerPage int = 3; SELECT * FROM GenresORDER BY GenreId ASC OFFSET @StartRow - 1 ROWS FETCH NEXT @RowsPerPage ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+

Hier verwende ich @StartRow int = 1, um anzugeben, dass die Ergebnisse in der ersten Zeile beginnen sollen.

Folgendes passiert, wenn ich diesen Wert auf 2 erhöhe.

DECLARE @StartRow int = 2, @RowsPerPage int = 3; SELECT * FROM GenresORDER BY GenreId ASC OFFSET @StartRow - 1 ROWS FETCH NEXT @RowsPerPage ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 2 | Jazz || 3 | Country || 4 | Pop |+-----------+---------+

Es beginnt in der zweiten Zeile. Mit dieser Methode kann ich die genaue Zeile angeben, in der ich beginnen soll.

Beispiel 5 – Paginierung nach Seitenzahl

Dieses Beispiel ist fast identisch mit dem vorherigen Beispiel, außer dass Sie die Seitenzahl im Gegensatz zur Zeilennummer angeben können.

DECLARE @PageNumber int = 1, @RowsPerPage int = 3; SELECT * FROM GenresORDER BY GenreId ASC OFFSET (@PageNumber - 1) * @RowsPerPage ROWS FETCH NEXT @RowsPerPage ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+

Das erste Ergebnis ist also dasselbe. Mal sehen, was passiert, wenn wir @PageNumber auf 2 erhöhen (ich habe diese Variable umbenannt, um ihren neuen Zweck widerzuspiegeln).

DECLARE @PageNumber int = 2, @RowsPerPage int = 3; SELECT * FROM GenresORDER BY GenreId ASC OFFSET (@PageNumber - 1) * @RowsPerPage ROWS FETCH NEXT @RowsPerPage ROWS ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 4 | Pop || 5 | Blues || 6 | Hip Hop |+-----------+---------+

Dieses Mal beginnen die Ergebnisse in der vierten Zeile. Mit dieser Methode können Sie also einfach die Seitenzahl anstelle der Zeilennummer übergeben.

Beispiel 6 – Paginierungsschleife

Zum Abschluss finden Sie hier ein kurzes Beispiel, das alle Seiten durchläuft und die Startzeilennummer für jede Iteration angibt:

DECLARE @StartRow int = 1, @RowsPerPage int = 3;WHILE (SELECT COUNT(*) FROM Genres) >= @StartRow BEGIN SELECT * FROM Genres ORDER BY GenreId ASC OFFSET @StartRow - 1 ROWS FETCH NEXT @RowsPerPage ROWS ONLY;SET @StartRow = @StartRow + @RowsPerPage; CONTINUEEND;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+(3 rows affected)+-----------+---------+| GenreId | Genre ||-----------+---------|| 4 | Pop || 5 | Blues || 6 | Hip Hop |+-----------+---------+(3 rows affected)+-----------+---------+| GenreId | Genre ||-----------+---------|| 7 | Rap || 8 | Punk |+-----------+---------+(2 rows affected)

Beispiel 7 – ZEILE gegen ZEILE

Wenn Sie auf Code stoßen, derROW anstelle von ROWS machen beide Argumente dasselbe. Sie sind Synonyme und dienen der ANSI-Kompatibilität.

Hier ist das erste Beispiel auf dieser Seite, aber mit ROW anstelle von ROWS.

SELECT *FROM GenresORDER BY GenreId OFFSET 0 ROW FETCH NEXT 3 ROW ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+

Beispiel 8 – FIRST vs NEXT

Das gleiche gilt für FIRST und NEXT. Dies sind Synonyme, die für die ANSI-Kompatibilität bereitgestellt werden.

Hier ist das vorherige Beispiel, aber mit FIRST anstelle von NEXT.

SELECT *FROM GenresORDER BY GenreId OFFSET 0 ROW FETCH FIRST 3 ROW ONLY;

Ergebnis:

+-----------+---------+| GenreId | Genre ||-----------+---------|| 1 | Rock || 2 | Jazz || 3 | Country |+-----------+---------+

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.