Curseurs
[30 min]
Afin d'affiner l'analyse du profil de chaque client, le service marketing souhaite avoir un état pour chaque client avec le nombre de ses factures et son chiffre d'affaire total.
Question
Écrivez deux fonctions stockées qui prendront en argument un numéro de client, et retourneront sous forme de number le nombre de factures et le chiffre d'affaire, respectivement.
Indice
CREATE OR REPLACE FUNCTION nbfact(num_client NUMBER) RETURN NUMBER
...
END nbfact;/
SHOW ERRORSCREATE OR REPLACE FUNCTION ca (num_client NUMBER) RETURN NUMBER
...
END ca;/
SHOW ERRORSSolution
CREATE OR REPLACE FUNCTION nbfact(num_client NUMBER) RETURN NUMBER
IS nb NUMBER;BEGINSELECT COUNT(f.num) INTO nb
FROM facture f WHERE f.client=num_client; RETURN nb;END nbfact;/
SHOW ERRORSCREATE OR REPLACE FUNCTION ca (num_client NUMBER) RETURN NUMBER
IS ca NUMBER;BEGINSELECT sum(p.prix*lf.qte) INTO ca
FROM produit p, facture f, ligne_fact lf WHERE p.num=lf.produit AND lf.facture=f.num AND f.client=num_client; RETURN ca;END ca;/
SHOW ERRORSQuestion
Écrivez un programme PL/SQL anonyme qui affiche pour le client numéro 1 le nombre de factures et le chiffre d'affaire.
Indice
Pensez à exécuter le "SET SERVEROUTPUT ON" avant l'exécution de "DBMS_OUTPUT.PUT_LINE".
Indice
Utlisez la syntaxe DECLARE ... BEGIN ... END pour déclarer un bloc PL/SQL anonyme.
DECLARE client NUMBER; BEGIN client:=1;...
END;/
Solution
SET SERVEROUTPUT ON
DECLARE client NUMBER;BEGIN client:=1; DBMS_OUTPUT.PUT_LINE (nbfact(1)); DBMS_OUTPUT.PUT_LINE (ca(1));END;/
Question
Écrivez un second programme PL/SQL qui affiche pour chaque client son nombre de factures et son chiffre d'affaire sous la forme suivante :
Client 1
10 / 152.23
------------------
Client 2
5 / 123.34
------------------
...
Indice
Utiliser un curseur sur la table client :
CURSOR c_client IS SELECT num FROM client;
Indice
Utiliser le caractère de concaténation || pour afficher plusieurs informations sur une même ligne :
DBMS_OUTPUT.PUT_LINE('Client' || client.num);Solution
SET SERVEROUTPUT ON
DECLARECURSOR c_client IS SELECT num FROM client;
num client.num%TYPE;BEGIN OPEN c_client; LOOPFETCH c_client INTO num;
EXIT WHEN c_client%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Client' || num); DBMS_OUTPUT.PUT_LINE (nbfact(num) || '/' || ca(num)); DBMS_OUTPUT.PUT_LINE('-----------------');END LOOP;
END;/
Question
Transformez le bloc anonyme en procédure. Testez cette procédure.
Solution
CREATE OR REPLACE PROCEDURE pClient
ISCURSOR c_client IS SELECT num FROM client;
num client.num%TYPE;BEGIN OPEN c_client; LOOPFETCH c_client INTO num;
EXIT WHEN c_client%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Client' || num); DBMS_OUTPUT.PUT_LINE (nbfact(num) || '/' || ca(num)); DBMS_OUTPUT.PUT_LINE('-----------------');END LOOP;
END;/
SET SERVEROUTPUT ON
BEGINpClient;
END;/