Curseurs (SQL Server)

S’applique à :SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Les opérations réalisées dans une base de données relationnelle s'exécutent sur un ensemble complet de lignes. Par exemple, l’ensemble de lignes retourné par une instruction SELECT contient toutes les lignes satisfaisant aux conditions de la clause WHERE de l’instruction. Cet ensemble complet de lignes retournées par l’instruction est appelé jeu de résultats. Les applications, en particulier les applications en ligne interactives, ne peuvent pas toujours fonctionner efficacement avec l’ensemble du jeu de résultats en tant qu’unité. Ces applications ont besoin d'un mécanisme leur permettant de travailler avec une seule ligne ou avec un petit bloc de lignes à la fois. Les curseurs sont une extension des ensembles de résultats et fournissent ce mécanisme.

Les curseurs permettent l'extension du traitement des résultats en procédant aux opérations suivantes :

  • Ils permettent de vous positionner sur des lignes spécifiques de l'ensemble de résultats.

  • Ils extraient une ligne ou un bloc de lignes à partir de la position actuelle dans l'ensemble de résultats.

  • Ils prennent en charge les modifications de données apportées aux lignes à la position actuelle dans l'ensemble de résultats.

  • Ils prennent en charge différents niveaux de visibilité des modifications apportées par d'autres utilisateurs aux données de la base de données qui figurent dans l'ensemble de résultats.

  • Fournir des instructions Transact-SQL dans des scripts, des procédures stockées et déclenche l’accès aux données dans un jeu de résultats.

Notes

Dans certains scénarios, s’il existe une clé primaire sur une table, une WHILE boucle peut être utilisée au lieu d’un curseur, sans entraîner la surcharge d’un curseur.

Toutefois, il existe des scénarios où les curseurs ne sont pas seulement inévitables, ils sont réellement nécessaires. Lorsque c’est le cas, s’il n’est pas nécessaire de mettre à jour les tables en fonction du curseur, utilisez des curseurs firehose , ce qui signifie des curseurs rapides vers l’avant et en lecture seule .

Implémentations de curseurs

SQL Server prend en charge trois implémentations de curseur.

Implémentation du curseur Description
Curseurs Transact-SQL Les curseurs Transact-SQL sont basés sur la DECLARE CURSOR syntaxe et utilisés principalement dans les scripts Transact-SQL, les procédures stockées et les déclencheurs. Les curseurs Transact-SQL sont implémentés sur le serveur et sont gérés par des instructions Transact-SQL envoyées du client au serveur. Ils peuvent également être contenus dans des lots, des procédures stockées ou des déclencheurs.
Curseurs du serveur de l’interface de programmation d’applications (API) Les curseurs d’API prennent en charge les fonctions de curseur d’API comme OLE DB et ODBC. Les curseurs de serveur d'API sont implémentés sur le serveur. Chaque fois qu’une application cliente appelle une fonction de curseur d’API, le fournisseur OLE DB SQL Server Native Client ou le pilote ODBC transmet la demande au serveur pour une action sur le curseur du serveur d’API.
Curseurs clients Les curseurs clients sont implémentés en interne par le pilote ODBC SQL Server Native Client et par la DLL qui implémente l’API ADO. Les curseurs clients sont implémentés par la mise en mémoire cache sur le client de toutes les lignes de l'ensemble de résultats. Chaque fois qu’une application cliente appelle une fonction de curseur d’API, le pilote ODBC SQL Server Native Client ou la DLL ADO effectue l’opération de curseur sur les lignes du jeu de résultats mises en cache sur le client.

Type de curseurs

SQL Server prend en charge quatre types de curseurs.

Les curseurs peuvent utiliser tempdb des tables de travail. Tout comme les opérations d’agrégation ou de tri qui se déversent, ces coûts d’E/S entraînent et constituent un goulot d’étranglement potentiel des performances. Les curseurs STATIC utilisent des tables de travail dès leur création. Pour plus d’informations, consultez la section Des tables de travail dans le guide d’architecture de traitement des requêtes.

Curseur avant uniquement

Un curseur vers l’avant uniquement est spécifié comme FORWARD_ONLY et READ_ONLY ne prend pas en charge le défilement. Ces curseurs sont aussi appelés firehose et prennent en charge uniquement l’extraction des lignes en série du début jusqu’à la fin du curseur. Les lignes ne sont pas récupérées à partir de la base de données tant qu’elles ne sont pas récupérées. Les effets de toutes les instructions INSERT, UPDATE et DELETE émises par l’utilisateur actif ou validées par d’autres utilisateurs et ayant une incidence sur les lignes du jeu de résultats sont visibles à mesure que les lignes sont extraites à partir du curseur.

Étant donné que le curseur ne peut pas être fait défiler vers l’arrière, la plupart des modifications apportées aux lignes de la base de données après la récupération de la ligne ne sont pas visibles par le curseur. En revanche, si une valeur utilisée pour déterminer l'emplacement de la ligne dans le jeu de résultats est modifiée, par exemple dans le cas de la mise à jour d'une colonne couverte par un index cluster, la valeur modifiée est visible à l'aide du curseur.

Bien que les modèles de curseur d’API de base de données considèrent qu’un curseur vers l’avant uniquement est un type distinct de curseur, SQL Server ne le fait pas. SQL Server considère à la fois le transfert uniquement et le défilement en tant qu’options qui peuvent être appliquées aux curseurs statiques, pilotés par les jeux de clés et dynamiques. Les curseurs Transact-SQL prennent en charge les curseurs statiques, pilotés par les jeux de clés et dynamiques en avant uniquement. Les modèles de curseurs d'API de bases de données supposent que les curseurs statiques, de jeux de clés et dynamiques permettent toujours le défilement. Lorsqu’un attribut ou une propriété de curseur d’API de base de données est défini sur forward-only, SQL Server implémente ceci en tant que curseur dynamique vers l’avant uniquement.

statique

Le jeu de résultats complet d’un curseur statique est intégré tempdb lors de l’ouverture du curseur. Un curseur statique affiche toujours l'ensemble de résultats tel qu'il était au moment où le curseur a été ouvert. Les curseurs statiques détectent peu ou pas de modifications, mais consomment relativement peu de ressources pendant le défilement.

Le curseur ne reflète pas les modifications apportées dans la base de données qui affectent l’appartenance au jeu de résultats ou les modifications apportées aux valeurs des colonnes des lignes qui composent le jeu de résultats. Un curseur statique n’affiche pas de nouvelles lignes insérées dans la base de données après l’ouverture du curseur, même s’ils correspondent aux conditions de recherche de l’instruction de curseur SELECT . Si les lignes qui composent le jeu de résultats sont mises à jour par d’autres utilisateurs, les nouvelles valeurs de données ne sont pas affichées dans le curseur statique. Le curseur statique affiche les lignes supprimées de la base de données après l'ouverture du curseur. Aucune opération UPDATE, INSERT ou DELETE n’apparaît dans un curseur statique (à moins qu’il soit fermé et rouvert), ni même les modifications effectuée en utilisant la même connexion que celle qui a ouvert le curseur.

Remarque

Les curseurs statiques SQL Server sont toujours en lecture seule.

Étant donné que le jeu de résultats d’un curseur statique est stocké dans une table tempdbde travail, la taille des lignes du jeu de résultats ne peut pas dépasser la taille maximale de ligne d’une table SQL Server.

Pour plus d’informations, consultez la section Des tables de travail dans le guide d’architecture de traitement des requêtes. Pour plus d’informations sur la taille maximale des lignes, consultez Spécifications de capacité maximale pour SQL Server.

Transact-SQL utilise le terme insensible aux curseurs statiques. Certaines API de base de données les identifient en tant que curseurs instantané.

Keyset

L'appartenance et l'ordre des lignes d'un curseur de jeu de clés sont fixés au moment de l'ouverture du curseur. Les curseurs pilotés par l’ensemble de clés sont contrôlés par un ensemble d’identificateurs uniques ou de clés, appelés jeu de clés. Les clés sont créées à partir d'un ensemble de colonnes qui identifient uniquement les lignes de l'ensemble de résultats. Le jeu de clés est l’ensemble des valeurs de clés de toutes les lignes remplissant les conditions requises par l’instruction SELECT au moment où le curseur a été ouvert. L’ensemble de clés d’un curseur piloté par l’ensemble de clés est intégré tempdb lors de l’ouverture du curseur.

Dynamique

Les curseurs dynamiques sont le contraire des curseurs statiques. Les curseurs dynamiques reflètent toutes les modifications apportées aux lignes de leur jeu de résultats lorsque vous les parcourez. Les valeurs des données, l'ordre et l'appartenance des lignes du jeu de résultats peuvent changer à chaque extraction. Toutes les instructions UPDATE, INSERT et DELETE émises par l’ensemble des utilisateurs sont visibles à l’aide du curseur. Mises à jour sont visibles immédiatement s’ils sont effectués via le curseur à l’aide d’une fonction API telle que SQLSetPos ou de la clause Transact-SQLWHERE CURRENT OF. Mises à jour effectuée en dehors du curseur ne sont pas visibles tant qu’ils ne sont pas validés, sauf si le niveau d’isolation de transaction du curseur est défini pour lire non validé. Pour plus d’informations sur les niveaux d’isolation, consultez SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Remarque

Les plans de curseur dynamique n'utilisent jamais d'index spatiaux.

Demander un curseur

SQL Server prend en charge deux méthodes pour demander un curseur :

  • Transact-SQL

    Le langage Transact-SQL prend en charge une syntaxe permettant d’utiliser des curseurs modélisés après la syntaxe du curseur ISO.

  • Fonctions de curseur de l'interface de programmation d'application (API) de bases de données

    SQL Server prend en charge les fonctionnalités de curseur de ces API de base de données :

    • ADO (Microsoft ActiveX Data Object)

    • OLE DB

    • ODBC (Open Database Connectivity)

Une application ne doit jamais combiner ces deux méthodes de demande de curseur. Une application qui utilise l’API pour spécifier des comportements de curseur ne doit pas ensuite exécuter une instruction Transact-SQL DECLARE CURSOR pour demander également un curseur Transact-SQL. Une application ne doit s’exécuter DECLARE CURSOR que si elle définit tous les attributs de curseur d’API sur leurs valeurs par défaut.

Si aucun curseur Transact-SQL ni API n’est demandé, SQL Server retourne par défaut un jeu de résultats complet, appelé jeu de résultats par défaut, à l’application.

Processus de curseur

Les curseurs Transact-SQL et les curseurs d’API ont une syntaxe différente, mais le processus général suivant est utilisé avec tous les curseurs SQL Server :

  1. Associez un curseur au jeu de résultats d’une instruction Transact-SQL et définissez les caractéristiques du curseur, par exemple si les lignes du curseur peuvent être mises à jour.

  2. Exécutez l’instruction Transact-SQL pour remplir le curseur.

  3. Dans le curseur que vous voulez afficher, extrayez les lignes. L'opération consistant à récupérer une ligne ou un bloc de lignes à partir d'un curseur est appelée une extraction. Le défilement est l'opération consistant à effectuer une série d'extractions afin d'extraire des lignes vers l'avant ou vers l'arrière.

  4. Vous pouvez, si vous le souhaitez, effectuer des opérations de modification (mise à jour ou suppression) sur la ligne à la position actuelle du curseur.

  5. Fermez le curseur.