J'ai donc une fonction qui renvoie un certain nombre d'enregistrements pour lesquels je souhaite implémenter la pagination sur mon site Web. Il m'a été suggéré d'utiliser le décalage/extraction suivant dans SQL Server 2012 pour accomplir cela. Sur notre site Web, nous avons une zone qui répertorie le nombre total d'enregistrements et la page sur laquelle vous vous trouvez à ce moment-là.
Auparavant, je disposais de tout le jeu d'enregistrements et j'étais capable de construire la pagination sur ce programme. Mais en utilisant la méthode SQL avec FETCH NEXT X ROWS UNIQUEMENT, on ne me restitue que X rangées. Je ne sais donc pas quel est mon jeu d’enregistrements total ni comment calculer mes pages min et max. La seule façon pour moi de faire cela consiste à appeler la fonction deux fois et à compter les lignes sur la première, puis à exécuter la seconde avec FETCH NEXT. Existe-t-il un meilleur moyen de ne pas exécuter la requête deux fois? J'essaie d'accélérer les performances, pas de les ralentir.
Vous pouvez utiliser COUNT(*) OVER()
... voici un exemple rapide utilisant sys.all_objects
:
DECLARE
@PageSize INT = 10,
@PageNum INT = 1;
SELECT
name, object_id,
overall_count = COUNT(*) OVER()
FROM sys.all_objects
ORDER BY name
OFFSET (@PageNum-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;
Cependant, cela devrait être réservé aux petits ensembles de données; sur de plus grands ensembles, la performance peut être catastrophique. Voir cet article de Paul White pour de meilleures alternatives , y compris la gestion des vues indexées (qui ne fonctionne que si le résultat n'est pas filtré ou si vous connaissez les clauses WHERE
à l'avance) et l'utilisation de ROW_NUMBER()
des trucs.
J'ai rencontré des problèmes de performances lors de l'utilisation de la méthode COUNT () OVER (). Je ne sais pas s'il s'agissait du serveur, car il a fallu 40 secondes pour renvoyer 10 enregistrements, puis aucun problème ne s'est produit ultérieurement.) Cette technique a fonctionné dans toutes les conditions sans avoir à utiliser COUNT () OVER () et accomplit la même chose:
DECLARE
@PageSize INT = 10,
@PageNum INT = 1;
WITH TempResult AS(
SELECT ID, Name
FROM Table
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult, TempCount
ORDER BY TempResult.Name
OFFSET (@PageNum-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY
Basé sur réponse de James Moberg :
C'est une alternative en utilisant Row_Number()
, si vous n'avez pas SQL Server 2012 et que vous ne pouvez pas utiliser OFFSET.
DECLARE
@PageNumEnd INT = 10,
@PageNum INT = 1;
WITH TempResult AS(
SELECT ID, NAME
FROM Tabla
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
select *
from
(
SELECT
ROW_NUMBER() OVER ( ORDER BY PolizaId DESC) AS 'NumeroRenglon',
MaxRows,
ID,
Name
FROM TempResult, TempCount
)resultados
WHERE NumeroRenglon >= @PageNum
AND NumeroRenglon <= @PageNumEnd
ORDER BY NumeroRenglon