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 ERRORS
CREATE OR REPLACE FUNCTION ca (num_client NUMBER) RETURN NUMBER
...
END ca;
/
SHOW ERRORS
Solution
CREATE OR REPLACE FUNCTION nbfact(num_client NUMBER) RETURN NUMBER
IS
nb NUMBER;
BEGIN
SELECT COUNT(f.num) INTO nb
FROM facture f
WHERE f.client=num_client;
RETURN nb;
END nbfact;
/
SHOW ERRORS
CREATE OR REPLACE FUNCTION ca (num_client NUMBER) RETURN NUMBER
IS
ca NUMBER;
BEGIN
SELECT 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 ERRORS
Question
É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
DECLARE
CURSOR c_client IS SELECT num FROM client;
num client.num%TYPE;
BEGIN
OPEN c_client;
LOOP
FETCH 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
IS
CURSOR c_client IS SELECT num FROM client;
num client.num%TYPE;
BEGIN
OPEN c_client;
LOOP
FETCH 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
BEGIN
pClient;
END;
/