Les Cursseurs(Cursor)

Cursor est un type de données permet de stocker une liste (result de SELECT)
Les curseurs en MySQL sont principalement utilisés pour parcourir et traiter les résultats d'une requête SQL ligne par ligne.
Ils sont utiles lorsque vous avez besoin de manipuler des données en itérant sur chaque enregistrement résultant d'une requête.
Exemple En PHP
while($ligne=mysqli_fetch_assoc($res))
 {
traitement ligne par ligne
}
-->pour faire ceci en sql en utlise CURSOR
a.Syntaxe:Declaration

  declare cursor nomCursor for select ....
Exemple Créer une procedure qui prermet d'afficher la liste de clients et leur achats sous la forme '
nom prenom 
   liste produits
     produit 1 :30
	produit 2 :10

delimiter $$
create procedure clientAchat()
begin
declare tachat text default "";
declare listeproduit text default "";
declare vnom varchar(25),vprenom varchar(25),vidcli int;
declare fullname text default "";
declare vlibelle varchar(25),totalAchat int;
declare vfin int default 0;
 DECLARE CONTINUE HANDLER 
        FOR NOT FOUND SET vfin = 1;
		--Cursor pour afficher la liste de client
declare Cursor clientCursor  for select nom,prenom,idcli from client;
pointArret: LOOP
 FETCH clientCursor INTO vnom,vprenom,vidcli;
 IF vfin = 1 THEN 
 LEAVE pointArret;
 END IF;
set fullname=contact(vnom,' ',vprenom);
 set tachat=contact(tachat,' \n',fullname);
 set tachat=contact(tachat,' \n','liste produits \n');
  
  --Cursor pour afficher les produit achetés par ce client
  
  declare Cursor produitCursor  for select libelle,sum(v.qteVendue)  
            from produit p,vente v2
			where  v.idcli=vidcli
			and p.idpro=v.idpro
			group by v.idpro;
set listeproduit="";

pointArret2: LOOP
 FETCH produitCursor INTO vlibelle,totalAchat;
 IF vfin = 1 THEN 
 LEAVE pointArret2;
 END IF;
  
  set listeproduit=contact(listeproduit,'\n',vlibelle,':',totalAchat);
  
 END LOOP pointArret2;
 set vfin=0;
 CLOSE produitCursor;
 set tachat=concat(tachat,listeproduit);
  END LOOP pointArret;
 CLOSE clientCursor;
 select tachat;--afficher la liste
end;
Exemple
Crée une nouvelle procédure stockée nommée "parcourir_produits"
DELIMITER //
CREATE PROCEDURE parcourir_produits()
BEGIN
    DECLARE done INT DEFAULT 0;  -- Indicateur pour marquer la fin de la lecture
    DECLARE product_id INT;      -- Variable pour stocker l'ID du produit
    DECLARE product_name VARCHAR(255); -- Variable pour stocker le nom du produit
    DECLARE product_price DECIMAL(10, 2); -- Variable pour stocker le prix du produit
    
    -- Déclare un curseur pour récupérer les produits de la table "produits"
    DECLARE product_cursor CURSOR FOR
        SELECT id, libelle, prix FROM produits;
    
    -- Ignorer les déclencheurs temporaires
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
    OPEN product_cursor; -- Ouvre le curseur pour commencer la lecture
    
    read_loop: LOOP
        FETCH product_cursor INTO product_id, product_name, product_price; -- Lit l'enregistrement suivant
        
        IF done = 1 THEN -- Sort de la boucle si tous les enregistrements ont été lus
            LEAVE read_loop;
        END IF;
        
        -- Faites quelque chose avec les données du produit (par exemple, affichage)
        SELECT CONCAT('ID: ', product_id, ', Nom: ', product_name, ', Prix: ', product_price) AS result;
    END LOOP;
    
    CLOSE product_cursor; -- Ferme le curseur à la fin
    
END//
Exemple d'appel de la procédure

CALL parcourir_produits();
Exemple
Crée une nouvelle procédure stockée nommée "calculer_somme_prix"
DELIMITER $$
CREATE PROCEDURE calculer_somme_prix()
BEGIN
    DECLARE done INT DEFAULT 0; -- Indicateur pour marquer la fin de la lecture
    DECLARE total_price DECIMAL(10, 2) DEFAULT 0; -- Variable pour stocker la somme des prix
    DECLARE v_prix DECIMAL(10, 2) DEFAULT 0;
    
    -- Déclare un curseur pour récupérer les prix des produits de la table "produits"
    DECLARE price_cursor CURSOR FOR
        SELECT prix FROM produits;
    
    -- Ignorer les déclencheurs temporaires
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
    OPEN price_cursor; -- Ouvre le curseur pour commencer la lecture
    
    read_loop: LOOP
        FETCH price_cursor INTO v_prix; -- Lit le prix de l'enregistrement suivant
        
        IF done = 1 THEN -- Sort de la boucle si tous les enregistrements ont été lus
            LEAVE read_loop;
        END IF;
        
        -- Calcule la somme des prix
        SET total_price = total_price + v_prix;
    END LOOP;
    
    CLOSE price_cursor; -- Ferme le curseur à la fin
    
    -- Affiche la somme totale des prix
    SELECT 'La somme totale des prix est :', total_price;
    
END$$
Exemple d'appel de la procédure
CALL calculer_somme_prix();
Exemples
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour afficher tous les produits disponibles dans la table "produits."
    DELIMITER //
    CREATE PROCEDURE AfficherProduits()
    BEGIN
        DECLARE produit_id INT;
        DECLARE produit_nom VARCHAR(50);
    	DECLARE Done default 0;
        DECLARE cur CURSOR FOR SELECT id, nom FROM produits;
    	declare continue handler for not found set done=1; 
        
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO produit_id, produit_nom;
             if done=0 then
    		 leave read_loop;
    		 end if;
            SELECT produit_id, produit_nom;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour afficher tous les clients de la table "clients" dans une ville spécifique.
    DELIMITER //
    CREATE PROCEDURE ClientsDansVille(villeRecherche VARCHAR(50))
    BEGIN
        DECLARE client_id INT;
        DECLARE client_nom VARCHAR(50);
    	declare done int default 0;
        DECLARE cur CURSOR FOR SELECT id, nom FROM clients WHERE ville = villeRecherche;
        declare continue handler for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO client_id, client_nom;
             if done=1 then 
    		 leave read_loop;
    		 end if;
            SELECT client_id, client_nom;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour afficher toutes les ventes effectuées pour un client spécifique.
    DELIMITER //
    CREATE PROCEDURE VentesClient(client_id INT)
    BEGIN
        DECLARE vente_id INT;
        DECLARE produit_id INT;
        DECLARE date_vente DATE;
    	declare done int default 0;
        DECLARE cur CURSOR FOR SELECT idvente, idProduit, dateVente FROM ventes WHERE idClient = client_id;
        declare continue for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO vente_id, produit_id, date_vente;
             if done=1 then
    		 leave read_loop;
    		 end if;
            SELECT vente_id, produit_id, date_vente;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour mettre à jour les prix de tous les produits dans la table "produits" en ajoutant 10%.
    DELIMITER //
    CREATE PROCEDURE MiseAJourPrixProduits()
    BEGIN
        DECLARE produit_id INT;
        DECLARE produit_prix FLOAT;
    	declare done int default 0;
        DECLARE cur CURSOR FOR SELECT id, prix FROM produits;
        declare continue handler for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO produit_id, produit_prix;
            IF done=1 then
                LEAVE read_loop;
            END IF;
            UPDATE produits SET prix = produit_prix * 1.1 WHERE id = produit_id;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour afficher les produits vendus en quantité supérieure à un seuil spécifique.
    DELIMITER //
    CREATE PROCEDURE ProduitsVendusPlusQue(seuil INT)
    BEGIN
        DECLARE produit_id INT;
        DECLARE produit_nom VARCHAR(50);
        DECLARE quantite INT;
    	declare done int default 0;
        DECLARE cur CURSOR FOR
            SELECT p.id, p.nom, SUM(v.QuantiteVendue)
            FROM produits p
            JOIN ventes v ON p.id = v.idProduit
            GROUP BY p.id, p.nom
            HAVING SUM(v.QuantiteVendue) > seuil;
        declare  continue handler for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO produit_id, produit_nom, quantite;
            IF done=1 THEN
                LEAVE read_loop;
            END IF;
            SELECT produit_id, produit_nom, quantite;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour supprimer tous les produits dont la quantité en stock est inférieure à un seuil donné.
    DELIMITER //
    CREATE PROCEDURE SupprimerProduitsStockInferieurA(seuil INT)
    BEGIN
        DECLARE produit_id INT;
        declare done int default 0;
        DECLARE cur CURSOR FOR SELECT id FROM produits WHERE quantiteStock < seuil;
        declare continue handler for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO produit_id;
            IF done=1 THEN
                LEAVE read_loop;
            END IF;
            DELETE FROM produits WHERE id = produit_id;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;
    
    
  • Q(CURSOR): Créez une procédure stockée qui utilise un curseur pour mettre à jour la quantité en stock des produits en ajoutant un nombre spécifique.
    DELIMITER //
    CREATE PROCEDURE MiseAJourStockProduits(ajoutStock INT)
    BEGIN
        DECLARE produit_id INT;
        DECLARE produit_quantite INT;
    	declare done int default 0;
        DECLARE cur CURSOR FOR SELECT id, quantiteStock FROM produits;
        declare continue handler for not found set done=1;
        OPEN cur;
        read_loop: LOOP
            FETCH cur INTO produit_id, produit_quantite;
            IF done=1 THEN
                LEAVE read_loop;
            END IF;
            UPDATE produits SET quantiteStock = produit_quantite + ajoutStock WHERE id = produit_id;
        END LOOP;
        
        CLOSE cur;
    END;
    //
    DELIMITER ;