You are on page 1of 7

Tp 3 : PL/SQL

Partie 1 : Curseur Implicite/explicite

1. Afficher la liste des départements, leur identifiant, leur nom ainsi leur salaire moyen (vous
pouvez utiliser un curseur implicite ou explicite)

DECLARE

CURSOR dept_cursor IS

SELECT department_id, department_name, AVG(salary) AS avg_salary

FROM employees

JOIN departments ON employees.department_id = departments.department_id

GROUP BY department_id, department_name;

BEGIN

FOR dept_rec IN dept_cursor LOOP

DBMS_OUTPUT.PUT_LINE('Department ' || dept_rec.department_id || ' - ' ||


dept_rec.department_name ||

' - Average Salary: ' || dept_rec.avg_salary);

END LOOP;

END;

2. Afficher la liste des départements, leur identifiant, leur nom ainsi leur salaire moyen.

BEGIN

FOR dept_rec IN (SELECT department_id, department_name, AVG(salary) AS avg_salary

FROM employees

JOIN departments ON employees.department_id = departments.department_id

GROUP BY department_id, department_name) LOOP

DBMS_OUTPUT.PUT_LINE('Department ' || dept_rec.department_id || ' - ' ||


dept_rec.department_name ||

' - Average Salary: ' || dept_rec.avg_salary);

END LOOP;

END;
3. Afficher la liste des employés du département dont e salaire moyen de tous les employés
dépasse 5000

DECLARE

v_dept_id NUMBER := 60; -- ID du département concerné

v_dept_avg_salary NUMBER;

BEGIN

-- Calculer le salaire moyen du département

SELECT AVG(salary) INTO v_dept_avg_salary FROM employees WHERE department_id = v_dept_id;

-- Afficher la liste des employés avec un salaire supérieur au salaire moyen du département

FOR emp_rec IN (SELECT employee_id, first_name, last_name, salary

FROM employees

WHERE department_id = v_dept_id AND salary > v_dept_avg_salary) LOOP

DBMS_OUTPUT.PUT_LINE(emp_rec.employee_id || ' - ' || emp_rec.first_name || ' ' ||


emp_rec.last_name ||

' - Salary: ' || emp_rec.salary);

END LOOP;

END;

4. Afficher la liste des noms et prénoms des managers. pour chaque manager afficher les
noms et prénoms des employés qu’il dirige vous pouvez utiliser ces curceurs Cursor c1 is
select SELECT employee_id, first_name, last_name FROM employees where employee_id
in ( select manager_id from employees where manager_id is not null); Cursor c2(idM
employees.manager_id%type) is select last_name, first_name from employees where
manager_id=idM; var_c1 c1%rowtype; var_c2 c2%rowtype

DECLARE
CURSOR mgr_cursor IS
SELECT employee_id, first_name, last_name
FROM employees
WHERE employee_id IN (SELECT DISTINCT manager_id FROM employees WHERE
manager_id IS NOT NULL);

CURSOR emp_cursor(p_mgr_id NUMBER) IS


SELECT employee_id, first_name, last_name
FROM employees
WHERE manager_id = p_mgr_id;

v_mgr_id employees.employee_id%TYPE;
BEGIN
-- Afficher la liste des managers
FOR mgr_rec IN mgr_cursor LOOP
DB

Partie 2: Fonction et procédure stockées / les exceptions

1. n bloc anonyme permettant de créer les 2 tables suivantes : • Players (player_id,


last_name, first_name, salary, team_id#) • Teams (team_id, name, foundation_date,
players_number ,country) vous pouvez utiliser l’idée du vsql DECLARE vsql varchar(255); 1
TP3 BEGIN vsql:=’CREATE TABLE players(....)

DECLARE

vsql varchar(1000);

BEGIN

vsql := 'CREATE TABLE Players (player_id number(10) primary key, last_name varchar2(50),
first_name varchar2(50), salary number(10,2), team_id number(10))';

execute immediate vsql;

vsql := 'CREATE TABLE Teams (team_id number(10) primary key, name varchar2(50) unique,
foundation_date date, players_number number(10), country varchar2(50))';

execute immediate vsql;

dbms_output.put_line('Tables created successfully');

END;

2. Une procédure stockée « proc_insertion_team » permettant d’ajouter une nouvelle


equipe "team". Cette procédure doit vérifier que la référence est UNIQUE. (NB : le champ
« players_number » reste NULL). Utilisez cette procédure afin d’insérer 3 equipe.

CREATE OR REPLACE PROCEDURE proc_insertion_team (


p_team_id IN Teams.team_id%type,
p_name IN Teams.name%type,
p_foundation_date IN Teams.foundation_date%type,
p_country IN Teams.country%type
) IS
v_count NUMBER;
BEGIN
-- Vérifier que la référence est unique
SELECT count(*) INTO v_count FROM Teams WHERE team_id = p_team_id;
IF v_count > 0 THEN
dbms_output.put_line('Team reference already exists');
RETURN;
END IF;

-- Ajouter une nouvelle équipe


INSERT INTO Teams (team_id, name, foundation_date, country)
VALUES (p_team_id, p_name, p_foundation_date, p_country);

dbms_output.put_line('Team added successfully');


END;

3. Une procédure stockée « proc_insertion_player » permettant d’ajouter un nouvel joueur.


Cette procédure doit vérifier que : • Le id "player_id est UNIQUE • La référence de l’equipe
"team_id" EXISTE • le salaire pour chacun des joueur est au minimum 3000. Utilisez cette
procédure afin d’insérer 3 joueur.

CREATE OR REPLACE PROCEDURE proc_insertion_player (

p_player_id IN Players.player_id%type,

p_last_name IN Players.last_name%type,

p_first_name IN Players.first_name%type,

p_salary IN Players.salary%type,

p_team_id IN Players.team_id%type

) IS

v_count NUMBER;

BEGIN

-- Vérifier que le joueur_id est unique

SELECT count(*) INTO v_count FROM Players WHERE player_id = p_player_id;

IF v_count > 0 THEN

dbms_output.put_line('Player ID already exists');

RETURN;

END IF;
-- Vérifier que la référence de l'équipe existe

SELECT count(*) INTO v_count FROM Teams WHERE team_id = p_team_id;

IF v_count = 0 THEN

dbms_output.put_line('Team reference does not exist');

RETURN;

END IF;

-- Vérifier que le salaire est au minimum 3000

IF p_salary < 3000 THEN

dbms_output.put_line('Salary must be at least 3000');

RETURN;

END IF;

-- Ajouter un nouveau joueur

INSERT INTO Players (player_id, last_name, first_name, salary, team_id)

VALUES (p_player_id, p_last_name, p_first_name, p_salary, p_team_id);

dbms_output.put_line('Player added successfully');

END;

4. Modifier la procédure stockée précédente pour qu’elle retourne en plus le nombre TOTAL
des joueurs. 5. Une procédure stockée « proc_liste_joueurs » permettant de lister les
joueurs par equipe

CREATE OR REPLACE PROCEDURE proc_insertion_player (


p_player_id IN Players.player_id%type,
p_last_name IN Players.last_name%type,
p_first_name IN Players.first_name%type,
p_salary IN Players.salary%type,
p_team_id IN Players.team_id%type,
p_total OUT NUMBER
) IS
v_count NUMBER;
BEGIN
Partie 3: Les triggers

1. Créer un trigger « trig_messages » permettant d’afficher avant et après chaque insertion


dans la table joueur respectivement les messages suivants : « Début d’insertion » et « Fin
d’insertion »

CREATE OR REPLACE TRIGGER trig_messages


BEFORE INSERT ON joueur
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('Début d’insertion');
END;

CREATE OR REPLACE TRIGGER trig_messages


AFTER INSERT ON joueur
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('Fin d’insertion');
END;

2. Créer un trigger « trig_messages_specif » permettant d’afficher avant chaque insertion,


mise à jour ou suppression dans la table teams respectivement les messages suivants : «
Insertion le 01/04/2023 à 9H » OU « Modification le 01/04/2023 à 9H » ou « Suppression
le 01/04/2023 à 9H », indiquant l’action effectuée, l’heure et la date.

CREATE OR REPLACE TRIGGER trig_messages_specif


BEFORE INSERT OR UPDATE OR DELETE ON teams
FOR EACH ROW
DECLARE
v_action VARCHAR2(20);
BEGIN
IF INSERTING THEN
v_action := 'Insertion';
ELSIF UPDATING THEN
v_action := 'Modification';
ELSIF DELETING THEN
v_action := 'Suppression';
END IF;

DBMS_OUTPUT.PUT_LINE(v_action || ' le ' || TO_CHAR(SYSDATE, 'DD/MM/YYYY') || ' à '


|| TO_CHAR(SYSDATE, 'HH24:MI'));
END;
3. Créer un trigger « Trig_nbrjoueurs » permettant de mettre à jour la colonne «
players_number » après chaque nouvel affectation ou retrait d’un joueur.

CREATE OR REPLACE TRIGGER Trig_nbrjoueurs


AFTER INSERT OR DELETE ON joueur
FOR EACH ROW
DECLARE
v_team_id teams.team_id%TYPE;
BEGIN
v_team_id := :NEW.team_id#;

UPDATE teams
SET players_number = (SELECT COUNT(*) FROM joueur WHERE team_id# = v_team_id)
WHERE team_id = v_team_id;
END;

4. Créer un trigger nommé « Trig_control » permettant d’interdire toute opération LMD


(insert, delete, update) sur la table PLAYERS pendant les weekends

CREATE OR REPLACE TRIGGER Trig_control


BEFORE INSERT OR DELETE OR UPDATE ON players
FOR EACH ROW
DECLARE
v_day VARCHAR2(3);
BEGIN
v_day := TO_CHAR(SYSDATE, 'dy');

IF v_day = 'sat' OR v_day = 'sun' THEN


RAISE_APPLICATION_ERROR(-20001, 'Les opérations LMD sont interdites pendant les
weekends');
END IF;
END;

You might also like