Vous êtes sur la page 1sur 18

Introduction

 SQL fonctionne en se basant sur des ensembles


i.e. SELECT retourne un ensemble de lignes appelé ensemble de résultats

 Cependant, parfois, on a besoin de traiter cet ensemble de donnée ligne par ligne

C’est Là où réside l’intérêt des curseur


Un curseur : c’est quoi ?
 Un curseur d’une base de donnée est un objet/structure de données permettant de traverser
successivement les lignes d’un ensemble de résultats retournés par une requête. i.e. Il permet
de traiter chaque ligne de la requête individuellement.

 Le curseur est un pointeur sur des enregistrements dans une base de données

 Pour MS SQL Server, les curseurs sont explicites, ce qui veut dire qu’ils sont associés à une
requête SELECT bien précise.

Un curseur est en réalité un


buffer qui contient le résultat
Curseur Base de
d'une requête, c'est-à-dire un
données
certain nombre d'occurrences
(lignes)
Cycle de vie d’un curseur
• Il y a des étapes à suivre pour l’utilisation d’un curseur :

Declare Fetch

Close

open Non

Vide ?
Oui
Deallocate
Déclaration d’un curseur
 On commence par déclarer le curseur :

Le nom que vous allez attribuer à votre curseur


(On ne met pas de @ lors de la declaration d’un curseur)

DECLARE cursor_name CURSOR


FOR select_statement;

La requête select permet de définir


l’ensemble des résultats à parcourir avec le
curseur défini
 Cette instruction associe un curseur de base de données à une instruction SQL dans la
connexion en cours
Ouverture du curseur
 Après la déclaration, on ouvre le curseur :
Le nom que vous avez attribué à votre curseur

Open cursor_name

 Après l’ouverture, on récupère une ligne du curseur dans une ou plusieurs variables :

Fetch NEXT FROM cursor_name INTO variable_list;


Parcourir les lignes du curseur
 Après, pour parcourir toute les lignes du curseur, on passe par une boucle
@@fetch_status est une La variable système
qui permet de détecter la fin du curseur; elle
retourne le statut du curseur i.e.
While @@fetch_status = 0
 si elle retourne 0, donc il y a davantage de
Begin ligne à parcourir
-- Traitement à faire
Fetch NEXT FROM cursor_name INTO  Sinon (si la valeur est ≠ de 0), il n’y a plus de
variable_list; ligne à parcourir et on sort de la boucle.
End
Fermeture et désallocation du curseur
 Après avoir terminé, on doit fermer notre curseur
Le nom que vous avez attribué à votre curseur

Close cursor_name

 À la fin, on doit désallouer notre curseur de la mémoire

Deallocate cursor_name;
Récapitulatif
Declare curs_name Cursor for sql_statement Cet instruction permet de
pointer sur la première ligne de Table 1 Table 2 Table 3
Open cursor_name
la requête associée au curseur
Fetch NEXT FROM cursor_name INTO
variable_list; 1. …
2. …
3. …
While @@fetch_status = 0
Begin
-- Traitement à faire
Fetch next from cursor_name Into values_list;  La boucle permet de parcourir les autres lignes de la requête
End associée au curseur

Close cursor_name  La commande FETCH permet d’aller chercher chaque


Deallocate cursor_name enregistrement dans l’ensemble actif, une ligne à la fois.

 À chaque fois que le FETCH est utilisé, le curseur avance au


prochain enregistrement dans l’ensemble actif
Exemple 1. Déclaration des variables où on va stocker les valeurs
récupérées à partir des colonnes sélectionnées dans la
1.declare @numart int, @desig varchar(10), @pu real requête select
2. Déclaration d’un curseur qui va contenir les lignes
2.declare cur_art cursor for select numart, retournées par la requête select pour les colonnes
desi_art, pu_art from article numart, desi_art, pu_art
3. On ouvre le curseur
3.open cur_art 4. On récupère la première ligne avant d’accéder à la
4.fetch next from cur_art into @numart , @desig , boucle while, et on mets les valeurs récupérées, à partir
@pu des colonnes sélectionnées dans la requête, dans leurs
variables correspondantes
5.while (@@FETCH_STATUS = 0) 5. Tant qu’il y a des lignes à récupérer à partir du curseur,
Begin on va réitérer; @@Fetch_status détecte la fin du
6.print 'l''article numéro '+ convert(varchar(20),
curseur, tant qu’elle est égale à 0, c’est qu’il y a des
@numart) + ' portant la désignation '+ @desig +
lignes à parcourir; (on doit ouvrir le bloc BEGIN..
'coûte '+convert(varchar(20), @pu);
7.fetch next from cur_art into @numart , @desig ,
END, puisque la condition while comporte plus d’une
@pu instruction
end 6. on affiche un message comportant les variables
utilisées par le curseur; la fonction convert est utilisée
8.close cur_art pour convertir les types en chaine de caractère
9.deallocate cur_art 7. On ferme le curseur
8. On désalloue le curseur
(il ne faut jamais oublier de fermer et désallouer le curseur)
Application

1. Ecrire un programme qui pour chaque commande :


• Affiche le numéro et la date de commande sous la forme :
Commande N° : ……Effectuée le : ….
• La liste des articles associés
• Le montant de cette commande

2. Ecrire un programme qui pour chaque commande vérifie si cette


commande a au moins un article. Si c'est le cas affiche son numéro et la liste
de ses articles sinon affiche un message d'erreur 'Aucun article pour la
commande …. Elle sera supprimée et supprime cette commande
Curseur pour Update
• Des fois, Il nous arrive d’utiliser des curseurs pour parcourir une collection de lignes et les mettre à
jour. Dans ce type de situations, on peut utiliser un curseur de mise à jour,
BEGIN
DECLARE @Prix1 int;
DECLARE prix_cursor CURSOR FOR SELECT PUArt FROM Article  Le programme met à jour les prix des article
;
BEGIN  Cet exemple suit le même principe que
OPEN prix_cursor; l’exemple précédent; la différence est qu’au
FETCH NEXT FROM prix_cursor INTO @Prix1 ; lieu d’afficher le contenu du curseur, on met à
WHILE @@FETCH_STATUS=0
jour la table concernée de la base de donnée
BEGIN
IF @Prix1<300 UPDATE Article
Set PUArt=PUArt+(PUArt*0.1) WHERE CURRENTOF prix_cursor;  La clause current of permet une opération de
ELSE IF @Prix1 BETWEEN 300 AND 500 UPDATE Article mise à jour ou de suppression à la position
Set PUArt=PUArt+(PUArt*0.05) WHERE CURRENTOF prix_cursor; actuelle du curseur sans qu’il soit nécessaire
ELSE UPDATE Article de spécifier une clause where pour spécifier la
Set PUArt=PUArt+(PUArt*0.01) WHERE CURRENTOF prix_cursor; ligne à mettre à jour
FETCH NEXT FROM prix_cursor INTO @Prix1;
END;
CLOSE prix_cursor;
DEALLOCATE prix_cursor;
END;
Curseurs scrollables
 Par défaut, les curseurs sont Forward ONLY : ils ne sont pas scrollables.

 Lorsqu’un curseur est déclaré avec l’attribut SCROLL alors on peut accéder au contenu du
curseur par d’autres option de la fonction FETCH.

 Nous pouvons avoir accès à :


 La première ligne,
 La dernière ligne,
 Une position absolue, exemple accéder exactement à la ligne 2.
 Une position relative à partir d’une position prédéfinie.
Syntaxe : Curseurs scrollables
Déclaration du curseur : declare cur_name scroll cursor for select_statement

Ouverture du curseur : open cur_name;

Pour lire un enregistrement à partir d'un curseur


 Atteindre le premier enregistrement du curseur : Fetch First from nom_curseur into variable1, variable2,..
 Atteindre l'enregistrement du curseur suivant celui en cours : Fetch Next from nom_curseur into variable1, variable2,...
 Atteindre le dernier enregistrement du curseur : Fetch Last from nom_curseur into variable1, variable2,…
 Atteindre l'enregistrement se trouvant à la position n dans le curseur : Fetch absolute n from nom_curseur into
variable1,variable2,...
 Atteindre l'enregistrement se trouvant après n positions de la ligne en cours:
Fetch Relative Num_Ligne from nom_curseur into variable1,variable2,...
Exemple : Curseurs scrollables
declare @numart int, @desig varchar(10), @pu real
declare cur_art scroll cursor for
select numart, desi_art, pu_art from article
open cur_art;

print 'la première ligne ' Accéder à la 1ère ligne du curseur


fetch first from cur_art into @numart, @desig, @pu;
print concat(@numart, ' ', @desig, ' ', @pu);

print 'la dernière ligne ' Accéder à la dernière ligne du curseur


fetch last from cur_art into @numart, @desig, @pu;
print concat(@numart, ' ', @desig, ' ', @pu);
Accéder à La ligne 2 du curseur
print ' La ligne 2'
fetch absolute 2 from cur_art into @numart, @desig, @pu;
print concat(@numart, ' ', @desig, ' ', @pu);
Accéder à La ligne 2 après la position
print ' relative: la deuxième ligne après la ligne courante' courante du curseur
fetch relative 2 from cur_art into @numart, @desig, @pu;
print concat(@numart, ' ', @desig, ' ', @pu);

print ' relative : la deuxième ligne avant la ligne courante ' Accéder à La ligne 2 avant la position courante
fetch RELATIVE -2 from cur_art into @numart, @desig, @pu; du curseur
print concat(@numart, ' ', @desig, ' ', @pu);

print ' immédiatement avant l''emplacement courant' Accéder à la ligne qui est juste avant la ligne
fetch PRIOR from cur_art into @numart, @desig, @pu;
print concat(@numart, ' ', @desig, ' ', @pu); courante du curseur
Application
• Ecrire un programme permettant d’accéder directement à la première ligne du curseur
relatif aux clients (Nom, Prénom) avec le montant de leurs commandes par ordre
décroissant.
• Ensuite, afficher l’enregistrement se trouvant à la ligne N°3 du curseur,

• Afficher le contenu de la deuxième ligne après la position courante,

• Afficher l’enregistrement se trouvant immédiatement avant la position courante


Pourquoi utilise-t-on les curseurs ?
Dans les procédures SQL par exemple, un curseur vous permet de définir un
jeu de résultats (un ensemble de lignes de données) et d'exécuter une logique
complexe par ligne.

En utilisant la même mécanique, une procédure SQL peut également définir
un jeu de résultats et le renvoyer directement à l'appelant de la procédure
SQL ou à une application cliente.

(Les Procédures seront vues dans les chapitres suivants)


Inconvénient de l’utilisation des curseurs
 Les curseurs prennent de la mémoire et créent des plantages (Ils essayent de forcer la
technologie basée sur les ensembles dans des fonctionnalités non basées sur les
ensembles).

Il utilise plus de ressources car il crée un réseau aller-retour chaque fois qu'il obtient une
ligne du curseur.

 Par conséquent, En raison, les performances et la vitesse sont lentes.

Donc si vous avez besoin de juste afficher les lignes d’une table sans les traiter
une ligne à la fois, un « select » suffit

Vous aimerez peut-être aussi