Résultats de la pagination SQL Server 2005

Translate

Comment paginer les résultats dans SQL Server 2005?

Je l'ai essayé dans SQL Server 2000, mais il n'y avait aucun moyen fiable de le faire. Je me demande maintenant si SQL Server 2005 a une méthode intégrée?

Ce que j'entends par pagination, c'est, par exemple, si je liste les utilisateurs par leur nom d'utilisateur, je veux pouvoir renvoyer uniquement les 10 premiers enregistrements, puis les 10 prochains enregistrements et ainsi de suite.

Toute aide serait très appréciée.

This question and all comments follow the "Attribution Required."

Toutes les réponses

Pat
Translate

Vous pouvez utiliserthe Row_Number()fonction. Il est utilisé comme suit:

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users

D'où il produira un jeu de résultats avec unRowIDchamp que vous pouvez utiliser pour parcourir les pages.

SELECT * 
FROM 
    ( SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
      FROM Users 
    ) As RowResults
WHERE RowID Between 5 AND 10

etc

La source
Translate

Si vous essayez de l'obtenir dans une instruction (le total plus la pagination). Vous devrez peut-être explorer la prise en charge de SQL Server pour la clause partition by (fonctions de fenêtrage en termes SQL ANSI). Dans Oracle, la syntaxe est identique à l'exemple ci-dessus en utilisant row_number (), mais j'ai également ajouté une clause partition par pour obtenir le nombre total de lignes incluses avec chaque ligne retournée dans la pagination (le nombre total de lignes est de 1262):

SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
         ROW_NUMBER () OVER (ORDER BY 1) AS rn, uo.*
         FROM all_objects uo
         WHERE owner = 'CSEIS') x
WHERE rn BETWEEN 6 AND 10

Notez que j'ai where owner = 'CSEIS' et ma partition par est sur owner. Les résultats sont donc:

RN  TOTAL_ROWS  OWNER   OBJECT_NAME            OBJECT_TYPE
6   1262    CSEIS   CG$BDS_MODIFICATION_TYPES   TRIGGER
7   1262    CSEIS   CG$AUS_MODIFICATION_TYPES   TRIGGER
8   1262    CSEIS   CG$BDR_MODIFICATION_TYPES   TRIGGER
9   1262    CSEIS   CG$ADS_MODIFICATION_TYPES   TRIGGER
10  1262    CSEIS   CG$BIS_LANGUAGES            TRIGGER
La source
Translate

La réponse acceptée pour cela ne fonctionne pas vraiment pour moi ... J'ai dû sauter par un autre cerceau pour que cela fonctionne.

Quand j'ai essayé la réponse

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
WHERE RowID Between 0 AND 9

il a échoué, se plaignant de ne pas savoir ce qu'était RowID.

J'ai dû l'envelopper dans une sélection intérieure comme celle-ci:

SELECT * 
FROM
    (SELECT
    Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
    FROM Users
    ) innerSelect
WHERE RowID Between 0 AND 9

et puis ça a marché.

La source
Translate

Lorsque j'ai besoin de faire une pagination, j'utilise généralement également une table temporaire. Vous pouvez utiliser un paramètre de sortie pour renvoyer le nombre total d'enregistrements. Les instructions case dans la sélection vous permettent de trier les données sur des colonnes spécifiques sans avoir besoin de recourir à SQL dynamique.

--Declaration--

--Variables
@StartIndex INT,
@PageSize INT,
@SortColumn VARCHAR(50),
@SortDirection CHAR(3),
@Results INT OUTPUT

--Statements--
SELECT @Results = COUNT(ID) FROM Customers
WHERE FirstName LIKE '%a%'

SET @StartIndex = @StartIndex - 1 --Either do this here or in code, but be consistent
CREATE TABLE #Page(ROW INT IDENTITY(1,1) NOT NULL, id INT, sorting_1 SQL_VARIANT, sorting_2 SQL_VARIANT)
INSERT INTO #Page(ID, sorting_1, sorting_2)
SELECT TOP (@StartIndex + @PageSize)
    ID,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='ASC' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='ASC' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_1,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='DES' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='DES' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_2
FROM (
    SELECT
        CustomerId AS ID,
        FirstName,
        LastName
    FROM Customers
    WHERE
        FirstName LIKE '%a%'
) C
ORDER BY sort_1 ASC, sort_2 DESC, ID ASC;

SELECT
    ID,
    Customers.FirstName,
    Customers.LastName
FROM #Page
INNER JOIN Customers ON
    ID = Customers.CustomerId
WHERE ROW > @StartIndex AND ROW <= (@StartIndex + @PageSize)
ORDER BY ROW ASC

DROP TABLE #Page
La source
Pat
Translate

Je pense que vous devrez effectuer une requête distincte pour accomplir cela malheureusement.

J'ai pu accomplir cela à mon poste précédent en utilisant l'aide de cette page:Pagination dans DotNet 2.0

Ils le font également tirer un nombre de lignes séparément.

La source
Translate

Voici ce que je fais pour la pagination: toutes mes grosses requêtes qui doivent être paginées sont codées comme des insertions dans une table temporaire. La table temporaire a un champ d'identité qui agira de la même manière que le row_number () mentionné ci-dessus. Je stocke le nombre de lignes dans la table temporaire dans un paramètre de sortie afin que le code appelant sache combien il y a d'enregistrements totaux. Le code d'appel spécifie également la page souhaitée et le nombre de lignes par page qui sont sélectionnées dans la table temporaire.

La chose intéressante à faire de cette façon est que j'ai également un lien "Exporter" qui vous permet d'obtenir toutes les lignes du rapport renvoyées au format CSV au-dessus de chaque grille de mon application. Ce lien utilise la même procédure stockée: vous renvoyez simplement le contenu de la table temporaire au lieu de faire la logique de pagination. Cela apaise les utilisateurs qui détestent la pagination et veulent voirtoutet que vous souhaitez le trier d'un million de manières différentes.

La source