Disons que j'ai la variable de table simple suivante:
declare @databases table
(
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
Est-ce que déclarer et utiliser un curseur est ma seule option si je voulais parcourir les lignes? Y a-t-il un autre moyen?
sql-server
tsql
loops
Rayon
la source
la source
STATIC
option pour supprimer la relecture constante des tables de base et le verrouillage qui sont là par défaut et amènent la plupart des gens à croire à tort que les curseurs sont mauvais. @JacquesB très proche: revérifier pour voir si la ligne de résultat existe toujours + verrouillage sont les problèmes. EtSTATIC
corrige généralement cela :-).Réponses:
Tout d'abord, vous devez être absolument sûr que vous devez parcourir chaque ligne - les opérations basées sur les ensembles fonctionneront plus rapidement dans tous les cas auxquels je pense et utiliseront normalement du code plus simple.
Selon vos données, il peut être possible de boucler en utilisant uniquement des
SELECT
instructions, comme indiqué ci-dessous:Une autre alternative consiste à utiliser une table temporaire:
L'option que vous devez choisir dépend vraiment de la structure et du volume de vos données.
Remarque: Si vous utilisez SQL Server, vous seriez mieux servi en utilisant:
En utilisant
COUNT
devra toucher chaque ligne du tableau, leEXISTS
seul besoin de toucher la première (voir la réponse de Josef ci-dessous).la source
STATIC
option qui copie le jeu de résultats dans une table temporaire, et donc vous ne verrouillez ou ne revérifiez plus les tables de base :-).Juste une petite note, si vous utilisez SQL Server (2008 et supérieur), les exemples qui ont:
Serait mieux servi avec
Le comte devra toucher chaque ligne de la table, le
EXISTS
seul besoin de toucher la première.la source
Voici comment je le fais:
Pas de curseurs, pas de tables temporaires, pas de colonnes supplémentaires. La colonne USERID doit être un entier unique, comme le sont la plupart des clés primaires.
la source
Définissez votre table temporaire comme ceci -
Ensuite, faites ceci -
la source
Voici comment je le ferais:
[Modifier] Parce que j'ai probablement sauté le mot "variable" lors de ma première lecture de la question, voici une réponse mise à jour ...
la source
Si vous n'avez pas d'autre choix que d'aller ligne par ligne en créant un curseur FAST_FORWARD. Ce sera aussi rapide que de créer une boucle de temps et beaucoup plus facile à entretenir sur le long terme.
FAST_FORWARD Spécifie un curseur FORWARD_ONLY, READ_ONLY avec les optimisations de performances activées. FAST_FORWARD ne peut pas être spécifié si SCROLL ou FOR_UPDATE est également spécifié.
la source
FAST_FORWARD
curseur est une bonne solution. (vote positif)Une autre approche sans avoir à modifier votre schéma ou à utiliser des tables temporaires:
la source
Vous pouvez utiliser une boucle while:
la source
Cela fonctionnera dans la version SQL SERVER 2012.
la source
Léger, sans avoir à faire de tableaux supplémentaires, si vous avez un entier
ID
sur la tablela source
la source
Je ne vois vraiment pas pourquoi vous auriez besoin d'utiliser redouté
cursor
. Mais voici une autre option si vous utilisez SQL Server version 2005/2008Use Recursion
la source
Je vais fournir la solution basée sur un ensemble.
C'est beaucoup plus rapide que toute technique de boucle et plus facile à écrire et à maintenir.
la source
Je préfère utiliser l'Offset Fetch si vous avez un ID unique, vous pouvez trier votre table par:
De cette façon, je n'ai pas besoin d'ajouter des champs à la table ou d'utiliser une fonction de fenêtre.
la source
Il est possible d'utiliser un curseur pour cela:
la fonction create [dbo] .f_teste_loop renvoie la table @tabela (cod int, nome varchar (10)) comme begin
fin
créer la procédure [dbo]. [sp_teste_loop] as begin
fin
la source
Je suis d'accord avec le post précédent que les opérations basées sur des ensembles fonctionneront généralement mieux, mais si vous avez besoin d'itérer sur les lignes, voici l'approche que je prendrais:
Sélectionnez le prochain enregistrement inutilisé dans le tableau et répétez le processus
la source
Étape 1: L'instruction select ci-dessous crée une table temporaire avec un numéro de ligne unique pour chaque enregistrement.
Étape 2: Déclarez les variables requises
Étape 3: prendre le nombre total de lignes de la table temporaire
Étape 4: table de temp de boucle basée sur un numéro de ligne unique créé dans temp
la source
Cette approche ne nécessite qu'une seule variable et ne supprime aucune ligne de @databases. Je sais qu'il y a beaucoup de réponses ici, mais je n'en vois pas qui utilise MIN pour obtenir votre prochaine ID comme ça.
la source
Voici ma solution, qui utilise une boucle infinie, l'
BREAK
instruction et la@@ROWCOUNT
fonction. Aucun curseur ou table temporaire n'est nécessaire, et je n'ai besoin que d'écrire une requête pour obtenir la ligne suivante dans la@databases
table:la source
C'est le code que j'utilise 2008 R2. Ce code que j'utilise est de construire des index sur les champs clés (SSNO & EMPR_NO) n tous les contes
la source
serait mieux:
Évitez d'utiliser SELECT si vous ne faites pas référence à des tables ou si vous affectez simplement des valeurs.
la source