1.
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE CHANTIERS (
Reference VARCHAR2(10) PRIMARY KEY,
Lieu VARCHAR2(50),
DateDebut DATE,
Duree NUMBER,
nbrOuvrierAffectes NUMBER
)
';
EXECUTE IMMEDIATE '
CREATE TABLE OUVRIERS (
Matricule VARCHAR2(10) PRIMARY KEY,
Nom VARCHAR2(30),
Prenom VARCHAR2(30),
PrixJr NUMBER,
Ref VARCHAR2(10),
FOREIGN KEY (Ref) REFERENCES CHANTIERS(Reference)
)
';
END;
/
2.
CREATE OR REPLACE PROCEDURE proc_insertion_CHANTIER (
p_ref [Link]%TYPE,
p_lieu [Link]%TYPE,
p_datedebut [Link]%TYPE,
p_duree [Link]%TYPE
) IS
ref_deja_existante EXCEPTION;
BEGIN
-- Vérification si la référence existe déjà
DECLARE
v_dummy NUMBER;
BEGIN
SELECT 1 INTO v_dummy FROM CHANTIERS WHERE Reference = p_ref;
-- Si on arrive ici, c'est que la référence existe
RAISE ref_deja_existante;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Référence unique, on peut insérer
INSERT INTO CHANTIERS(Reference, Lieu, DateDebut, Duree,
nbrOuvrierAffectes)
VALUES(p_ref, p_lieu, p_datedebut, p_duree, NULL);
END;
EXCEPTION
WHEN ref_deja_existante THEN
DBMS_OUTPUT.PUT_LINE('Erreur : la référence "' || p_ref || '" existe
déjà.');
END;
/
test:
BEGIN
proc_insertion_CHANTIER('CH01', 'Tunis', TO_DATE('2025-05-01', 'YYYY-MM-DD'),
30);
proc_insertion_CHANTIER('CH02', 'Sfax', TO_DATE('2025-06-15', 'YYYY-MM-DD'),
20);
proc_insertion_CHANTIER('CH03', 'Sousse', TO_DATE('2025-07-10', 'YYYY-MM-DD'),
25);
END;
/
3. CREATE OR REPLACE PROCEDURE proc_insertion_OUVRIER (
p_matricule [Link]%TYPE,
p_nom [Link]%TYPE,
p_prenom [Link]%TYPE,
p_prixjr [Link]%TYPE,
p_ref [Link]%TYPE
) IS
matricule_existe EXCEPTION;
chantier_inexistant EXCEPTION;
prix_insuffisant EXCEPTION;
v_dummy NUMBER;
BEGIN
-- Vérifier si le matricule existe déjà
BEGIN
SELECT 1 INTO v_dummy FROM OUVRIERS WHERE Matricule = p_matricule;
RAISE matricule_existe;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
-- Vérifier si le chantier existe
BEGIN
SELECT 1 INTO v_dummy FROM CHANTIERS WHERE Reference = p_ref;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE chantier_inexistant;
END;
-- Vérifier le prix journalier
IF p_prixjr < 10 THEN
RAISE prix_insuffisant;
END IF;
-- Si tout est valide, insérer l’ouvrier
INSERT INTO OUVRIERS(Matricule, Nom, Prenom, PrixJr, Ref)
VALUES(p_matricule, p_nom, p_prenom, p_prixjr, p_ref);
DBMS_OUTPUT.PUT_LINE('Insertion réussie de l''ouvrier : ' || p_matricule);
EXCEPTION
WHEN matricule_existe THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Matricule "' || p_matricule || '" déjà
utilisé.');
WHEN chantier_inexistant THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Chantier avec référence "' || p_ref || '"
inexistant.');
WHEN prix_insuffisant THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Le prix journalier doit être >= 10
dinars.');
END;
/
BEGIN
proc_insertion_OUVRIER('O1', 'Ali', 'Ben Salah', 20, 'CH01');
proc_insertion_OUVRIER('O2', 'Nour', 'Ben Youssef', 12, 'CH02');
proc_insertion_OUVRIER('O3', 'Salim', 'Mhiri', 9, 'CH03'); -- Doit échouer
(prix < 10)
END;
/
4.
CREATE OR REPLACE PROCEDURE proc_insertion_OUVRIER (
p_matricule [Link]%TYPE,
p_nom [Link]%TYPE,
p_prenom [Link]%TYPE,
p_prixjr [Link]%TYPE,
p_ref [Link]%TYPE,
p_totalOuvriers OUT NUMBER
) IS
matricule_existe EXCEPTION;
chantier_inexistant EXCEPTION;
prix_insuffisant EXCEPTION;
v_dummy NUMBER;
BEGIN
-- Vérifier si le matricule existe déjà
BEGIN
SELECT 1 INTO v_dummy FROM OUVRIERS WHERE Matricule = p_matricule;
RAISE matricule_existe;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
-- Vérifier si le chantier existe
BEGIN
SELECT 1 INTO v_dummy FROM CHANTIERS WHERE Reference = p_ref;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE chantier_inexistant;
END;
-- Vérifier le prix journalier
IF p_prixjr < 10 THEN
RAISE prix_insuffisant;
END IF;
-- Insertion
INSERT INTO OUVRIERS(Matricule, Nom, Prenom, PrixJr, Ref)
VALUES(p_matricule, p_nom, p_prenom, p_prixjr, p_ref);
-- Retourner le nombre total d’ouvriers
SELECT COUNT(*) INTO p_totalOuvriers FROM OUVRIERS;
DBMS_OUTPUT.PUT_LINE('Insertion réussie. Total ouvriers = ' ||
p_totalOuvriers);
EXCEPTION
WHEN matricule_existe THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Matricule ' || p_matricule || ' déjà
utilisé.');
p_totalOuvriers := NULL;
WHEN chantier_inexistant THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Chantier avec référence ' || p_ref || '
inexistant.');
p_totalOuvriers := NULL;
WHEN prix_insuffisant THEN
DBMS_OUTPUT.PUT_LINE('Erreur : Le prix journalier doit être >= 10
dinars.');
p_totalOuvriers := NULL;
END;
/
test:
DECLARE
v_total NUMBER;
BEGIN
proc_insertion_OUVRIER('O4', 'Firas', 'Trabelsi', 15, 'CH01', v_total);
DBMS_OUTPUT.PUT_LINE('Nombre total d''ouvriers après insertion : ' || v_total);
END;
/
[Link] OR REPLACE FUNCTION fn_fin_chantier (
p_ref [Link]%TYPE
) RETURN DATE IS
v_dateFin DATE;
BEGIN
SELECT DateDebut + Duree
INTO v_dateFin
FROM CHANTIERS
WHERE Reference = p_ref;
RETURN v_dateFin;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Erreur : chantier inexistant.');
RETURN NULL;
END;
/
test:
DECLARE
v_fin DATE;
BEGIN
v_fin := fn_fin_chantier('CH01');
DBMS_OUTPUT.PUT_LINE('Date de fin du chantier CH01 : ' || TO_CHAR(v_fin, 'YYYY-
MM-DD'));
END;
/
6.
CREATE OR REPLACE PROCEDURE proc_liste_ouvriers (
p_ref [Link]%TYPE
) IS
BEGIN
FOR ouv IN (
SELECT Matricule, Nom, Prenom, PrixJr
FROM OUVRIERS
WHERE Ref = p_ref
) LOOP
DBMS_OUTPUT.PUT_LINE(
'Matricule: ' || [Link] || ', Nom: ' || [Link] || ', Prénom: '
|| [Link] || ', Prix/Jour: ' || [Link]
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Erreur lors de la récupération des ouvriers.');
END;
/
test:
BEGIN
proc_liste_ouvriers('CH01');
END;
/