Paging

Eintrag zuletzt aktualisiert am: 20.10.2015

Paging bedeutet grundsätzlich, Daten seitenweise zu verarbeiten. Wenn man Paging in der Benutzeroberfläche verwendet, dann muss der Benutzer explizit durch eine Aktion (Klick auf eine Schaltfläche) zur nächsten Seite blättern. Das ist ein beliebtes UI-Design-Muster in klassischen Webanwendungen. Aber diese Vorgehensweise ist verpönt in Desktop-Anwendungen und modernen Web-Anwendungen.

Paging auf Datenbankebene bedeutet, nicht eine gesamte Datenmenge vom Datenbankmanagementsystem abzuholen, sondern aus einer Ergebnismenge nur eine Teilmenge anhand der Position in der Ergebnismenge: Beispielsweise die Datensätze 1000 bis 1100 von 200.000 Datensätzen.

Wer schon einmal Paging in SQL realisiert hat, weiß, dass das die Syntax kein Spaß ist – zumindest nicht in Datenbankmanagementsystemen, die nicht keine Row Limiting Clauses mit den Schlüsselwörtern OFFSET, FETCH FIRST und FETCH NEXT aus dem SQL-ANSI-Standard des Jahres 2008 (ISO/IEC 9075:2008, siehe [1]) unterstützen. Microsoft bietet diese Unterstützung im Microsoft SQL Server ab Version 2012 (erschienen am 2.4.2012) an. Oracle bietet es seit Version 12c (erschienen am 1.7.2013).

So eine Row Limiting Clauses sieht in ANSI-SQL so aus:

SELECT * from [Betrieb].Flug order by FlugNr OFFSET 101 ROWS FETCH NEXT 100 ROWS ONLY;

Dabei gelten folgende Regeln:
  • FETCH kann nur zusammen mit OFFSET verwendet werden.
  • Das Sortieren des Resultsets mit ORDER BY ist verpflichtend.
  • TOP kann nicht mit OFFSET und FETCH kombiniert werden.
  • Die Werte bei OFFSET und FETCH müssen Ganzzahlen sein.

In älteren Versionen verwendet man die (nicht standardardisierte) rownumber()-Funktion in Verbindung mit dem Schlüsselwort TOP und einem Sub-Select, wobei es hier syntaktische Unterschiede zwischen Microsoft SQL Server und Oracle gibt. Listing 1 zeigt den TSQL-Befehl für Microsoft SQL Server, der die Datensätze 501 bis 600 aus der Datenbanktabelle "Flug" lädt.

SELECT TOP (100) *
FROM (
SELECT *,
rownumber() OVER (ORDER BY [FlugNr] ASC) AS [rownumber]
FROM [Betrieb].[Flug]
) AS f
WHERE f.[row_number] > 100
ORDER BY f.[FlugNr] ASC