Y a-t-il une valeur que je peux utiliser dans un SELECT TOP qui retournera toutes les lignes?

13

J'autorise l'utilisateur final à définir le nombre de lignes renvoyées par une requête (SELECT TOP (@x)). Y a-t-il une valeur qui peut être entrée où toutes les lignes sont retournées? Ou dois-je créer dynamiquement la requête sans TOP (@x) s'ils veulent que toutes les lignes soient retournées?

J'utilise SQL Server 2012.

Wayne E. Pfeffer
la source
C'est TOP ... ORDER BYquelque chose? Est-ce que ORDER BYquelque chose est toujours requis dans le cas où vous sélectionnez tout?
Martin Smith
1
Je suppose que euhhh ... simplement omettre le TOPhors de question? Comme si vous avez affaire à une requête prédéfinie et que vous devez lui transmettre quelque chose ?
corsiKa

Réponses:

17

Eh bien, il semble que TOP soit un BIGINT si vous n'utilisez pas un PERCENT . Cela signifie que vous pouvez transmettre la valeur maximale de BIGINT ,

SELECT TOP (9223372036854775807) * FROM table1

Je doute sérieusement que vous verrez jamais une table aussi grande. Je ne sais pas quel type d'effet cela aurait sur le plan de requête.

Kenneth Fisher
la source
7
En supposant que la variable @xest un BIGINT, cela SET @x = 0x7fffffffffffffffpeut être plus clair pour certains. C'est plus facile à retenir de toute façon.
Martin Smith
@MartinSmith Je vais être honnête, je vais le chercher de toute façon :) Je n'ai jamais vu ça avant cependant. Est-ce une conversion implicite?
Kenneth Fisher
7
Eh bien, il est plus facile de se souvenir si vous vous souvenez juste de commencer 7, puis le reste est Fet vous avez besoin de 16 caractères au total pour les 8 octets. Et oui, il sera implicitement converti s'il est attribué à une variable de ce type de données.
Martin Smith
@MartinSmith Est-ce une bonne pratique de s'appuyer sur une représentation binaire de la valeur? La documentation indique que la représentation binaire d'une valeur peut changer d'une version à une autre de SQL Server . De plus, je ne sais pas si je suis la seule personne, qui a toujours été confuse par la 0x7fffffffffffffffreprésentation de la valeur maximale de bigintSqlServer. La raison en est que dans la notation constante binaire SqlServer, vous avez 7fdans l' octet le plus bas , où, comme dans les langages comme c ++, vous l'avez dans l' octet le plus élevé pour obtenir le maximum du type intégral signé.
i-one
3
@ i-one. Il est extrêmement peu probable que la représentation binaire des types entiers change. Il ne servirait à rien que SQL Server fournisse des opérateurs au niveau du bit qui fonctionnent sur les types entiers si l'on ne s'attendait pas à ce que nous puissions compter sur un format spécifique.
Martin Smith
12

Vous pourriez également envisager

SET ROWCOUNT @x;

SELECT Foo
FROM Bar
ORDER BY Baz;

Au lieu de

SELECT TOP (@x) Foo
FROM Bar 
ORDER BY Baz;

La valeur à laquelle vous devez définir @x est 0de le désactiver.

Ceci est déconseillé pour les instructions de modification de données mais pas déconseillé pour SELECT.

En 2012, un plan différent est compilé pour le cas qui ROWCOUNTest 0 contre une valeur non nulle.

Si le ORDER BY Bazest uniquement là pour donner un sens au TOPplutôt que pour fournir un ordre de présentation des résultats et que vous n'avez pas d'index le supportant, alors la division en deux requêtes éviterait un tri inutile dans le 0cas.

Martin Smith
la source
8

SELECT TOP 100 PERCENT peut être utilisé pour contourner toute erreur lors de l'utilisation de "TOP" dans une requête.

MguerraTorres
la source
1
Pour moi, cela n'explique pas vraiment la raison d'utiliser une fonctionnalité optimisée. Crystal Reports s'attend-il à ce qu'un ORDER BY soit présent dans la définition de la vue?
Andriy M
Non, Crystal Reports a du mal à s'emparer des requêtes et à forcer ses propres plans d'exécution, ce qui les rend très inefficaces et parfois inexactes. Je préfère faire TOUTE ma logique et ma conception dans la requête SQL, et simplement la rendre "jolie" dans Crystal. C'est pourquoi j'ai, pour la plupart, migré vers SSIS / SSRS, mais il existe toujours des rapports hérités.
MguerraTorres
-2
select top(SELECT COUNT(*) FROM YourTable) * From YourTable
Abhilash Medi
la source
1
La question est de paramétrer la clause TOP. L'OP a déjà un paramètre ( @x) là-bas, et ils demandent maintenant à quelle valeur passer @xafin que cela signifie «toutes les lignes» quel que soit le nombre de lignes que la table possède réellement. Peut-être pourriez-vous comprendre comment adapter votre solution aux exigences du PO.
Andriy M
1
J'ai fait les ajustements pour répondre à la question, mais comme écrit, cela a une condition de concurrence si des lignes sont insérées simultanément. Cela nécessiterait un verrou de table pendant la durée pour résoudre ce blocage des insertions simultanées. Cela et les frais supplémentaires de vérification en premier lieu peuvent être évités en utilisant simplement un grand nombre.
Martin Smith
(SELECT COUNT(*) FROM YourTable)n'est pas une valeur.
ypercubeᵀᴹ